From d5154e0c3030fa2abb35400732eefcb970537d6e Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 21 Mar 2024 16:35:41 +0530 Subject: [PATCH 001/108] INFRA-2219 | Harinder | Adding JIT(just in time) package and migrations --- .../v2/jit/controller/JitController.java | 95 + .../portal/v2/jit/dto/JitRequestDTO.java | 43 + .../portal/v2/jit/dto/JitResponseDTO.java | 27 + .../infra/portal/v2/jit/dto/JitUserDTO.java | 17 + .../portal/v2/jit/entity/Environment.java | 17 + .../portal/v2/jit/entity/JitApproval.java | 59 + .../portal/v2/jit/entity/JitRequest.java | 96 + .../v2/jit/entity/JitRequestStatus.java | 8 + .../infra/portal/v2/jit/entity/Vertical.java | 13 + .../repository/JitApprovalsRepository.java | 22 + .../jit/repository/JitRequestsRepository.java | 12 + .../portal/v2/jit/service/JitService.java | 17 + .../portal/v2/jit/service/JitServiceImpl.java | 484 ++++ .../portal/v2/jit/utils/validateRequest.java | 4 + ...V1.68__Add_just_in_time_requests_table.sql | 18 + ...1.69__Add_just_in_time_approvals_table.sql | 10 + .../V1.70__Add_jit_roles_privileges.sql | 2181 +++++++++++++++++ ...71__Alter_user_table_add_slack_user_id.sql | 1 + 18 files changed, 3124 insertions(+) create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDTO.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/dto/JitResponseDTO.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/dto/JitUserDTO.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequestStatus.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/utils/validateRequest.java create mode 100644 src/main/resources/db/migration/V1.68__Add_just_in_time_requests_table.sql create mode 100644 src/main/resources/db/migration/V1.69__Add_just_in_time_approvals_table.sql create mode 100644 src/main/resources/db/migration/V1.70__Add_jit_roles_privileges.sql create mode 100644 src/main/resources/db/migration/V1.71__Alter_user_table_add_slack_user_id.sql diff --git a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java new file mode 100644 index 00000000..05ee2333 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java @@ -0,0 +1,95 @@ +package com.navi.infra.portal.v2.jit.controller; + +import com.navi.infra.portal.v2.jit.dto.JitResponseDTO; +import com.navi.infra.portal.v2.jit.dto.JitUserDTO; +import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; +import java.io.IOException; +import java.util.List; +import javax.validation.Valid; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Controller; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import com.navi.infra.portal.v2.jit.dto.JitRequestDTO; +import com.navi.infra.portal.v2.jit.service.JitService; + +@Controller +@RestController +@CrossOrigin +@RequiredArgsConstructor +@Slf4j +@RequestMapping("/api/jit") +public class JitController { + + private final JitService jitService; + + @PostMapping + public ResponseEntity createJitRequest(@Valid @RequestBody JitRequestDTO jitRequestDto) { + try { + return jitService.createJitRequest(jitRequestDto) + ? ResponseEntity.status(HttpStatus.CREATED).build() + : ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } catch (IllegalArgumentException | IOException ex) { + log.error("Exception: ", ex.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + } + + @PostMapping("/approve/{reviewId}") + public ResponseEntity approveJitRequest(@RequestBody JitUserDTO approver, @PathVariable Long reviewId ) { + try { + return jitService.approveJitRequest(approver.getUser(), reviewId) == -1 + ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() + : ResponseEntity.status(HttpStatus.OK).build(); + } catch (Exception ex) { + log.error("Exception: ", ex.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + } + + @PostMapping("/reject/{reviewId}") + public ResponseEntity rejectJitRequest(@RequestBody JitUserDTO rejecter, @PathVariable Long reviewId) { + try { + return jitService.rejectJitRequest(rejecter.getUser(), reviewId) == -1 + ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() + : ResponseEntity.status(HttpStatus.OK).build(); + } catch (Exception ex) { + log.error("Exception: ", ex.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + } + +// @PostMapping("/status/{id}") +// public ResponseEntity getJitRequestStatus(@RequestBody JitUserDTO checker, @PathVariable Long id) { +// try { +// JitResponseDTO jitResponse = jitService.getJitRequestStatus(checker.getUser(), id); +// return jitResponse.getId() == -1 +// ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() +// : ResponseEntity.ok(jitResponse); +// } catch (Exception ex) { +// log.error("Exception: ", ex.getMessage()); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); +// } +// } + + @PostMapping("/close/{id}") + public ResponseEntity closeJitRequest(@RequestBody JitUserDTO closer, @PathVariable Long id) { + try { + JitResponseDTO jitResponse = jitService.closeRequest(closer.getUser(), id); + return jitResponse.getId() == -1 + ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() + : ResponseEntity.status(HttpStatus.OK).build(); + } catch (Exception ex) { + log.error("Exception: ", ex.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + } +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDTO.java b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDTO.java new file mode 100644 index 00000000..df4e45f8 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDTO.java @@ -0,0 +1,43 @@ +package com.navi.infra.portal.v2.jit.dto; + +import com.navi.infra.portal.v2.jit.entity.Environment; +import com.navi.infra.portal.v2.jit.entity.Vertical; +import java.time.LocalDateTime; +import java.util.Date; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Positive; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +//@Builder +@NoArgsConstructor +@AllArgsConstructor +public class JitRequestDTO { + @Email + private String requestedFor; + + @Email + private String requestedBy; + + private Vertical vertical; + + private String team; + + private Environment environment; + + private String resourceType; + + private String resourceId; + + private String resourceAction; // READ, WRITE, MASTER, ADMIN ETC + + @Positive + private Long grantWindow; + + private LocalDateTime grantAt; +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitResponseDTO.java b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitResponseDTO.java new file mode 100644 index 00000000..d9de72d5 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitResponseDTO.java @@ -0,0 +1,27 @@ +package com.navi.infra.portal.v2.jit.dto; + +import com.navi.infra.portal.v2.jit.entity.JitApproval; +import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; +import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class JitResponseDTO { + private Long id; + + private JitRequestStatus jitRequestStatus; + + private List pendingReviews; + + public JitResponseDTO(long id, JitRequestStatus jitRequestStatus, List pendingReviews) { + this.id = id; + this.jitRequestStatus = jitRequestStatus; + this.pendingReviews = pendingReviews; + } +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitUserDTO.java b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitUserDTO.java new file mode 100644 index 00000000..51ff16ff --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitUserDTO.java @@ -0,0 +1,17 @@ +package com.navi.infra.portal.v2.jit.dto; + +import javax.validation.constraints.Email; +import javax.validation.constraints.Positive; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class JitUserDTO { + @Email + private String user; +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java new file mode 100644 index 00000000..09d43510 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java @@ -0,0 +1,17 @@ +package com.navi.infra.portal.v2.jit.entity; + +public enum Environment { + DEV("dev"), + QA("qa"), + PROD("prod"), + NONPROD("nonprod"), + CMD("cmd"), + PERF("perf"), + UAT("uat"), + DATA_PLATFORM_NONPROD("data-platform-nonprod"), + DATA_PLATFORM_PROD("data-platform-prod"); + + public final String type; + + Environment(String type) {this.type = type;} +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java new file mode 100644 index 00000000..391b45e1 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java @@ -0,0 +1,59 @@ +package com.navi.infra.portal.v2.jit.entity; + +import static lombok.AccessLevel.PACKAGE; + +import com.navi.infra.portal.domain.BaseEntity; +import com.navi.infra.portal.domain.user.User; +import java.time.LocalDateTime; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Column; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; + +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@NoArgsConstructor +@AllArgsConstructor(access = PACKAGE) +@Getter +@Setter +@Table(name = "jit_approvals") +public class JitApproval extends BaseEntity { + private static final long serialVersionUID = -1852998120471377502L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "jit_id", nullable = false) + private JitRequest jitRequest; + + @ManyToOne + @JoinColumn(name = "reviewer_id", nullable = false) + private User reviewer; + + @Column(nullable = false) + private LocalDateTime reviewedAt; + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private JitRequestStatus action; + + private String slackMessageTimestamp; + + public JitApproval(JitRequest jitRequest, User reviewer, JitRequestStatus action) { + this.jitRequest = jitRequest; + this.reviewer = reviewer; + this.action = action; + } +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java new file mode 100644 index 00000000..ee84d5c3 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java @@ -0,0 +1,96 @@ +package com.navi.infra.portal.v2.jit.entity; + +import com.navi.infra.portal.domain.BaseEntity; +import com.navi.infra.portal.domain.user.Team; +import com.navi.infra.portal.domain.user.User; +import java.time.LocalDateTime; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@Table(name = "jit_requests") +public class JitRequest extends BaseEntity { + + private static final long serialVersionUID = -1852998120471377502L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "requested_for_id", nullable = false) + private User requestedFor; + + @ManyToOne + @JoinColumn(name = "requested_by_id", nullable = false) + private User requestedBy; + + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private Vertical vertical; + + @ManyToOne + @JoinColumn(name = "team_id", nullable = false) + private Team team; + + @Enumerated(EnumType.STRING) + private Environment environment; + + private String resourceType; + + private String resourceId; + + private String resourceAction; + + @Enumerated(EnumType.STRING) + private JitRequestStatus status; + + @Column(nullable = false) + private Long grantWindow; + + private LocalDateTime grantAt; + + private String personalSlackMessageTimestamp; + + private String groupSlackMessageTimestamp; + + public JitRequest( + User requestedFor, + User requestedBy, + Vertical vertical, + Team team, + Environment environment, + String resourceType, + String resourceId, + String resourceAction, + JitRequestStatus status, + Long grantWindow, + LocalDateTime grantAt + ) { + this.requestedFor = requestedFor; + this.requestedBy = requestedBy; + this.vertical = vertical; + this.team = team; + this.environment = environment; + this.resourceType = resourceType; + this.resourceId = resourceId; + this.resourceAction = resourceAction; + this.status = status; + this.grantWindow = grantWindow; + this.grantAt = grantAt; + } +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequestStatus.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequestStatus.java new file mode 100644 index 00000000..a753f0f7 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequestStatus.java @@ -0,0 +1,8 @@ +package com.navi.infra.portal.v2.jit.entity; + +public enum JitRequestStatus { + PENDING, + APPROVED, + REJECTED, + CANCELLED +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java new file mode 100644 index 00000000..9924cacf --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java @@ -0,0 +1,13 @@ +package com.navi.infra.portal.v2.jit.entity; + +public enum Vertical { + GI("GI"), + NAVIPAY("navi-pay"), + SA("sa"), + LENDING("lending"), + NAVIPPL("navi-ppl"); + + public final String type; + + Vertical(String type) {this.type = type;} +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java new file mode 100644 index 00000000..93526313 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java @@ -0,0 +1,22 @@ +package com.navi.infra.portal.v2.jit.repository; + +import com.navi.infra.portal.v2.jit.entity.JitApproval; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +@Repository +public interface JitApprovalsRepository extends JpaRepository { + @Query(value = "SELECT ja.reviewer_id FROM jit_approvals ja WHERE ja.id = :id", nativeQuery = true) + String findReviewerId(Long id); + + @Query(value = "SELECT ja FROM jit_approvals ja WHERE ja.id = :jit_id", nativeQuery = true) + List findAllReviewsByJitId(Long jit_id); + + @Query(value="SELECT COUNT(ja.reviewer_id) FROM jit_approvals ja WHERE ja.jit_id = :jit_id", nativeQuery = true) + Long findApprovedRequestsCount(Long jit_id); + + @Query(value="SELECT ja.reviewer_id FROM jit_approvals ja WHERE ja.jit_id = :jit_id and lower(ja.action) = :action", nativeQuery = true) + List findReviewersByAction(Long jit_id, String action); +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java new file mode 100644 index 00000000..9c5f8fa5 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java @@ -0,0 +1,12 @@ +package com.navi.infra.portal.v2.jit.repository; + +import com.navi.infra.portal.v2.jit.entity.JitRequest; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +@Repository +public interface JitRequestsRepository extends JpaRepository { + @Query(value = "UPDATE jit_requests jr SET jr.status=CANCELLED WHERE ja.id = :jit_id", nativeQuery = true) + void updateRequestStatus(Long jit_id); +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java new file mode 100644 index 00000000..954980f0 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java @@ -0,0 +1,17 @@ +package com.navi.infra.portal.v2.jit.service; + +import com.navi.infra.portal.v2.jit.dto.JitRequestDTO; +import com.navi.infra.portal.v2.jit.dto.JitResponseDTO; +import java.io.IOException; + +public interface JitService { + Boolean createJitRequest (JitRequestDTO jitRequestDTO) throws IOException; + + Integer approveJitRequest(String approver, Long requestId) throws IOException; + + Integer rejectJitRequest(String rejecter, Long requestId) throws IOException; + +// JitResponseDTO getJitRequestStatus(String checker, Long requestId); + + JitResponseDTO closeRequest(String closer, Long requestId); +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java new file mode 100644 index 00000000..51ccc72c --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -0,0 +1,484 @@ +package com.navi.infra.portal.v2.jit.service; + +import static com.navi.infra.portal.v2.role.Actor.JITREVIEWER; + +import com.navi.infra.portal.domain.user.Role; +import com.navi.infra.portal.domain.user.User; +import com.navi.infra.portal.dto.slack.SlackMessageBlockType; +import com.navi.infra.portal.dto.slack.SlackMessageText; +import com.navi.infra.portal.dto.slack.SlackMessageTextType; +import com.navi.infra.portal.service.user.UserService; +import com.navi.infra.portal.v2.client.airflow.AirflowClient; +import com.navi.infra.portal.v2.jit.dto.JitRequestDTO; +import com.navi.infra.portal.v2.jit.dto.JitResponseDTO; +import com.navi.infra.portal.v2.jit.entity.Environment; +import com.navi.infra.portal.v2.jit.entity.JitApproval; +import com.navi.infra.portal.v2.jit.entity.JitRequest; +import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; +import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; +import com.navi.infra.portal.v2.jit.repository.JitRequestsRepository; +import com.navi.infra.portal.v2.privilege.ResourceType; +import com.navi.infra.portal.v2.role.RoleService; +import com.navi.infra.portal.v2.slackbotclient.SlackBotAttachment; +import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; +import com.navi.infra.portal.v2.slackbotclient.SlackBotMessageBlock; +import com.navi.infra.portal.v2.slackbotclient.SlackElementStyle; +import com.navi.infra.portal.v2.slackbotclient.SlackElementType; +import com.navi.infra.portal.v2.slackbotclient.SlackMessageElement; +import com.navi.infra.portal.v2.team.TeamService; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class JitServiceImpl implements JitService { + + private final AirflowClient airflowClient; + private final SlackBotClient slackBotClient; + private final UserService userService; + private final RoleService roleService; + private final TeamService teamService; + private final JitRequestsRepository jitRequestRepository; + private final JitApprovalsRepository jitApprovalsRepository; + private final ResourceType resourceType = null; + private final String env = null; + @Value("${jit.number_of_prod_approvals}") + private final Long prodJitApprovalsCount; + @Value("${jit.number_of_nonprod_approvals}") + private final Long nonprodJitApprovalsCount; + @Value("${jit.dag.id}") + private final String dagId; + + @Value("${jit.slack.common.channel.id}") + private final String commonChannelId; + + public JitServiceImpl( + AirflowClient airflowClient, + SlackBotClient slackBotClient, + UserService userService, + RoleService roleService, + TeamService teamService, + JitRequestsRepository jitRequestRepository, + JitApprovalsRepository jitApprovalsRepository, + @Value("${jit.dag.id}") String dagId, + @Value("${jit.number_of_prod_approvals}") Long prodJitApprovalsCount, + @Value("${jit.number_of_nonprod_approvals}") Long nonprodJitApprovalsCount, + String commonChannelId + ) { + this.airflowClient = airflowClient; + this.slackBotClient = slackBotClient; + this.userService = userService; + this.roleService = roleService; + this.teamService = teamService; + this.jitRequestRepository = jitRequestRepository; + this.jitApprovalsRepository = jitApprovalsRepository; + this.dagId = dagId; + this.prodJitApprovalsCount = prodJitApprovalsCount; + this.nonprodJitApprovalsCount = nonprodJitApprovalsCount; + this.commonChannelId = commonChannelId; + } + + private Boolean checkRequiredApprovals(JitRequest jitRequest) { + Environment env = jitRequest.getEnvironment(); + Long approvedRequests = jitApprovalsRepository.findApprovedRequestsCount( + jitRequest.getId()); + if ((env.equals(Environment.PROD) || env.equals(Environment.CMD) || env.equals( + Environment.DATA_PLATFORM_PROD)) && approvedRequests >= prodJitApprovalsCount) { + return true; + } else if ((env.equals(Environment.NONPROD) || env.equals(Environment.DEV) || env.equals( + Environment.QA) || env.equals(Environment.DATA_PLATFORM_NONPROD) || env.equals( + Environment.UAT) || env.equals(Environment.PERF)) + && approvedRequests >= nonprodJitApprovalsCount) { + return true; + } + return false; + } + + private boolean isAuthorized(String user, JitRequest jitRequest) { + List userRolesId = userService.listAllRolesOfUser(user); + List userRoles = roleService.listAllAuthorities(userRolesId); + + return userRoles.stream().filter( + role -> role.contains(JITREVIEWER.toString()) && role.contains( + jitRequest.getTeam().getName())).anyMatch( + role -> role.contains(jitRequest.getEnvironment().toString()) || role.contains("ALL")); + } + + private List getReviewersByAction( + UserService userService, Long jitId, JitRequestStatus jitRequestStatus + ) { + return userService.findAllByIds( + jitApprovalsRepository.findReviewersByAction(jitId, jitRequestStatus.toString())) + .parallelStream().map(User::getEmail).collect(Collectors.toList()); + } + + private void updateReviewerMessageOnSlack(User reviewer, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled) + throws IOException { + SlackBotAttachment reviewMessage = getReviewerMessage( + jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled); + String messageTimestamp = slackBotClient.postMessage( + userService.getSlackId(reviewer.getEmail()), reviewMessage); + jitApproval.setSlackMessageTimestamp(messageTimestamp); + } + + private void updatePersonalMessageOnSlack(JitRequest jitRequest, List pendingReviewers, List approvedReviewers, List rejectedReviewers, boolean actionEnabled) + throws IOException { + SlackBotAttachment personalMessage = getPersonalMessage( + jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingReviewers, + approvedReviewers, rejectedReviewers, jitRequest.getStatus().toString()); + String messageTimestamp = slackBotClient.postMessage( + userService.getSlackId(jitRequest.getRequestedBy().getEmail()), personalMessage); + jitRequest.setPersonalSlackMessageTimestamp(messageTimestamp); + } + + private void updateGroupMessageOnSlack(JitRequest jitRequest, List pendingReviewers, List approvedReviewers, List rejectedReviewers) + throws IOException { + SlackBotAttachment commonChannelMessage = getGroupMessage(jitRequest, + jitRequest.getRequestedFor().getEmail(), pendingReviewers, approvedReviewers, rejectedReviewers); + String messageTimestamp = slackBotClient.postMessage(commonChannelId, commonChannelMessage); + jitRequest.setGroupSlackMessageTimestamp(messageTimestamp); + } + + private Integer processJitRequest( + String reviewerEmail, Long requestId, JitFlowFunction flowFunction + ) throws IOException { + Optional jA = jitApprovalsRepository.findById(requestId); + + if (jA.isPresent()) { + JitApproval jitApproval = jA.get(); + if (jitApproval.getReviewedAt() != null) { + log.error("Request already reviewed"); + return -1; + } + jitApproval.setReviewedAt(LocalDateTime.now()); + JitRequest jitRequest = jitApproval.getJitRequest(); + + if (!reviewerEmail.equals(jitApproval.getReviewer().getEmail()) && !isAuthorized( + reviewerEmail, jitRequest) && reviewerEmail.equals( + jitRequest.getRequestedFor().getEmail())) { + log.error("User {} not allowed to perform action", reviewerEmail); + return -1; + } + + jitApproval.setReviewer(userService.findUserByEmail(reviewerEmail)); + return flowFunction.apply(reviewerEmail, jitApproval, jitRequest); + } + log.error("Illegal request"); + return -1; + } + + private Integer jitApprovedFlow( + String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest + ) throws IOException { + + try { + jitApprovalsRepository.save(jitApproval); + + List pendingReviewers = getReviewersByAction(userService, jitRequest.getId(), + JitRequestStatus.PENDING); + List approvedReviewers = getReviewersByAction(userService, jitRequest.getId(), + JitRequestStatus.APPROVED); + List rejectedReviewers = getReviewersByAction(userService, jitRequest.getId(), + JitRequestStatus.REJECTED); + + // inform reviewer on slack that request is approved and remove action buttons + updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + + // send group message to common channel with details on pending and approved reviewers + updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); + + Boolean actionEnabled = true; + + if (checkRequiredApprovals(jitRequest)) { + // if required number of approvals are met, + // 1. schedule JIT(just in time) DAGs - one for grant and another for grant, + // 2. inform user on slack that request is approved, + // 3. update the status in jit_approvals and jit_requests, + airflowClient.triggerJitDag(jitRequest, dagId, "runId-1", "grant"); + airflowClient.triggerJitDag(jitRequest, dagId, "runId-2", "revoke"); + + jitRequest.setStatus(JitRequestStatus.APPROVED); + + actionEnabled = false; + } + updatePersonalMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers, actionEnabled); + + jitRequestRepository.save(jitRequest); + jitApprovalsRepository.save(jitApproval); + return 0; + } catch (Exception e) { + log.error("Failed to connect to airflow or failed to flush to DB", e.getCause()); + return -1; + } + } + + private Integer jitCancelledFlow( + String closerEmail, JitRequest jitRequest + ) { + try { + jitRequest.setStatus(JitRequestStatus.CANCELLED); + List jitApprovals = jitApprovalsRepository.findAllReviewsByJitId(jitRequest.getId()).stream().map(JitApproval::getId).collect(Collectors.toList()); + for (Long approvalId : jitApprovals) { + JitApproval jitApproval = jitApprovalsRepository.findById(approvalId).get(); + jitApproval.setAction(JitRequestStatus.CANCELLED); + jitApprovalsRepository.save(jitApproval); + updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + } + updateGroupMessageOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); + updatePersonalMessageOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), false); + jitRequestRepository.save(jitRequest); + return 0; + } catch (Exception e) { + log.error("Failed to connect to airflow or failed to flush to DB", e.getCause()); + return -1; + } + } + + private Integer jitRejectedFlow( + String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest + ) { + try { + jitApproval.setAction(JitRequestStatus.REJECTED); + jitRequest.setStatus(JitRequestStatus.REJECTED); + + List pendingReviewers = getReviewersByAction(userService, jitRequest.getId(), + JitRequestStatus.PENDING); + List approvedReviewers = getReviewersByAction(userService, jitRequest.getId(), + JitRequestStatus.APPROVED); + List rejectedReviewers = getReviewersByAction(userService, jitRequest.getId(), + JitRequestStatus.REJECTED); + + updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + updatePersonalMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers, false); + updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); + + jitApprovalsRepository.save(jitApproval); + jitRequestRepository.save(jitRequest); + + return 0; + } catch (Exception e) { + log.error("Failed to connect to airflow or failed to flush to DB", e.getCause()); + return -1; + } + } + + private JitRequest mapToJitRequest(JitRequestDTO jitRequestDTO) { + return new JitRequest(userService.findUserByEmail(jitRequestDTO.getRequestedFor()), + userService.findUserByEmail(jitRequestDTO.getRequestedBy()), + jitRequestDTO.getVertical(), teamService.findByName(jitRequestDTO.getTeam()), + jitRequestDTO.getEnvironment(), jitRequestDTO.getResourceType(), + jitRequestDTO.getResourceId(), jitRequestDTO.getResourceAction(), + JitRequestStatus.PENDING, jitRequestDTO.getGrantWindow(), jitRequestDTO.getGrantAt()); + } + + private SlackBotAttachment getReviewerMessage( + String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled + ) { + ArrayList blocks = new ArrayList<>(); + + SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, + String.format("Access request reviewed for user %s\n" + "\t*Vertical*\n" + "\t%s\n\n" + + "\t*Environment*\t\t\t\t\t*Resource*\n" + "\t%s\t\t\t\t\t\t\t\t %s\n\n" + + "\t*Grant At/On*\t\t\t\t\t*Grant Window(In hours)*\n" + "\t%s\t\t %s\n\n" + + "Request status: %s", userEmail, jitRequest.getVertical().toString(), + jitRequest.getEnvironment().toString(), jitRequest.getResourceType(), + jitRequest.getGrantAt().truncatedTo(ChronoUnit.MINUTES), + jitRequest.getGrantWindow(), jitApproval.getAction().toString())); + SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( + SlackMessageBlockType.SECTION, reviewRequestText, null); + blocks.add(reviewRequestSection); + + if (actionEnabled){ + SlackMessageText approveText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, + "Approve"); + SlackMessageElement approveButton = new SlackMessageElement(SlackElementType.BUTTON, + approveText, SlackElementStyle.PRIMARY, + String.join("-", jitRequest.getId().toString(), jitApproval.getReviewer().getEmail()), + "actionApprove"); + + SlackMessageText rejectText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, + "Reject"); + SlackMessageElement rejectButton = new SlackMessageElement(SlackElementType.BUTTON, + rejectText, SlackElementStyle.DANGER, + String.join("-", jitRequest.getId().toString(), jitApproval.getReviewer().getEmail()), + "actionReject"); + + ArrayList elements = new ArrayList<>(); + elements.add(approveButton); + elements.add(rejectButton); + + SlackBotMessageBlock reviewRequestAction = new SlackBotMessageBlock( + SlackMessageBlockType.ACTIONS, null, elements); + + blocks.add(reviewRequestAction); + } + + return new SlackBotAttachment("#f2c744", blocks); + } + + private SlackBotAttachment getPersonalMessage( + String userEmail, + JitRequest jitRequest, + Boolean actionEnabled, + List pendingReviewers, + List approvedReviewers, + List rejectedReviewers, + String requestStatus + ) { + SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, + String.format("Access request raised for user %s\n" + "\tPending Reviewers: %s\n" + + "\tApproved Reviewers: %s\n" + "\tRejected Reviewers: %s\n" + + "\tCurrent Status: %s\n", userEmail, pendingReviewers.toString(), + approvedReviewers.toString(), rejectedReviewers.toString(), requestStatus)); + + SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( + SlackMessageBlockType.SECTION, reviewRequestText, null); + + SlackMessageText rejectText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, + "Reject"); + SlackMessageElement closeButton = new SlackMessageElement(SlackElementType.BUTTON, + rejectText, SlackElementStyle.DANGER, jitRequest.getId().toString(), "actionClose"); + + ArrayList blocks = new ArrayList<>(); + blocks.add(reviewRequestSection); + + if (actionEnabled) { + ArrayList elements = new ArrayList<>(); + elements.add(closeButton); + SlackBotMessageBlock reviewRequestAction = new SlackBotMessageBlock( + SlackMessageBlockType.ACTIONS, null, elements); + blocks.add(reviewRequestAction); + } + + return new SlackBotAttachment("#f2c744", blocks); + } + + private SlackBotAttachment getGroupMessage(JitRequest jitRequest, + String email, List pendingReviewers, List approvedReviewers, List rejectedReviewers + ) { + SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, + String.format("Access request raised for user %s\n" + "\tPending Reviewers: %s\n" + + "\tApproved By: %s\n\tRejected By: %s\n\tCurrent status: %s", email, pendingReviewers.toString(), + approvedReviewers.toString(), rejectedReviewers.toString(), jitRequest.getStatus().toString())); + + SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( + SlackMessageBlockType.SECTION, reviewRequestText, null); + + ArrayList blocks = new ArrayList<>(); + blocks.add(reviewRequestSection); + return new SlackBotAttachment("#f2c744", blocks); + } + + @Override + public Boolean createJitRequest(JitRequestDTO jitRequestDTO) throws IOException { + // validations here + if (jitRequestDTO.getGrantAt() == null) { + jitRequestDTO.setGrantAt(LocalDateTime.now()); + } else if (jitRequestDTO.getGrantAt().isBefore(LocalDateTime.now())) { + log.error("Invalid time: {} is before now {}", jitRequestDTO.getGrantAt(), + LocalDateTime.now()); + return false; + } + + // Map request DTO to JitRequest Entity and save in DB + JitRequest jitRequest = mapToJitRequest(jitRequestDTO); + + // Determine the reviewers based on REQUEST + Role reviewerRole = new Role(String.join("_", jitRequestDTO.getTeam(), + jitRequestDTO.getEnvironment().toString().toLowerCase(), JITREVIEWER.toString())); + List reviewers = userService.getUsersWithRole(reviewerRole.getName()); + reviewerRole = new Role( + String.join("_", jitRequestDTO.getTeam(), "ALL", JITREVIEWER.toString())); + + reviewers.addAll(userService.getUsersWithRole(reviewerRole.getName())); + log.info("Requesting review from {}", reviewers); + + List jitApprovals = new ArrayList<>(); + List pendingReviewers = new ArrayList<>(); + String messageTimestamp = ""; + for (User reviewer : reviewers) { + if (reviewer.getEmail().equals(jitRequest.getRequestedFor().getEmail())) { + continue; + } + JitApproval jitApproval = new JitApproval(jitRequest, reviewer, + JitRequestStatus.PENDING); + jitApprovals.add(jitApproval); + + // send review request to reviewers + String reviewersEmail = reviewer.getEmail(); + pendingReviewers.add(reviewersEmail); + + updateReviewerMessageOnSlack(reviewer, jitRequest, jitApproval, true); + } + // send personal message to user with details on pending and approved reviewers + updatePersonalMessageOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), new ArrayList<>(), true); + + // send group message to common channel with details on pending and approved reviewers + updateGroupMessageOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), new ArrayList<>()); + + jitApprovalsRepository.saveAll(jitApprovals); + jitRequestRepository.save(jitRequest); + + return true; + } + + @Override + public Integer approveJitRequest(String approver, Long requestId) throws IOException { + return processJitRequest(approver, requestId, this::jitApprovedFlow); + } + + @Override + public Integer rejectJitRequest(String rejecter, Long requestId) throws IOException { + return processJitRequest(rejecter, requestId, this::jitRejectedFlow); + } + +// @Override +// public JitResponseDTO getJitRequestStatus(String checker, Long requestId) { +// // verify if checker does have to permission to read JIT requests, +// // if so then inform about pending reviews +// Optional jitRequests = jitRequestRepository.findById(requestId); +// if (jitRequests.isPresent()) { +// JitRequest jR = jitRequests.get(); +// if (jR.getRequestedFor().getEmail().equals(checker)) { +// // use slackClient to update original message as well +// return new JitResponseDTO(jR.getId(), jR.getStatus(), new ArrayList<>()); +// } else { +// log.error("User {} not allowed to check request status", checker); +// return new JitResponseDTO(-1, null, null); +// } +// } +// return new JitResponseDTO(-1, null, null); +// } + + @Override + public JitResponseDTO closeRequest(String closer, Long requestId) { + Optional jitRequests = jitRequestRepository.findById(requestId); + if (jitRequests.isPresent()) { + JitRequest jitRequest = jitRequests.get(); + if (jitRequest.getRequestedFor().getEmail().equals(closer)) { + jitRequestRepository.updateRequestStatus(requestId); + jitCancelledFlow(closer, jitRequest); + } else { + log.error("User {} not allowed to reject request", closer); + return new JitResponseDTO(-1, null, null); + } + return new JitResponseDTO(requestId, jitRequests.get().getStatus(), null); + } + return null; + } + + @FunctionalInterface + interface JitFlowFunction { + + Integer apply(String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest) + throws IOException; + } +} \ No newline at end of file diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/validateRequest.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/validateRequest.java new file mode 100644 index 00000000..a9f63776 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/validateRequest.java @@ -0,0 +1,4 @@ +package com.navi.infra.portal.v2.jit.utils; + +public class validateRequest { +} diff --git a/src/main/resources/db/migration/V1.68__Add_just_in_time_requests_table.sql b/src/main/resources/db/migration/V1.68__Add_just_in_time_requests_table.sql new file mode 100644 index 00000000..cc73058a --- /dev/null +++ b/src/main/resources/db/migration/V1.68__Add_just_in_time_requests_table.sql @@ -0,0 +1,18 @@ +CREATE TABLE jit_requests ( + id BIGSERIAL PRIMARY KEY, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + requested_for_id BIGINT NOT NULL REFERENCES users(id), + requested_by_id BIGINT NOT NULL REFERENCES users(id), + vertical character varying(255), + team_id BIGINT NOT NULL REFERENCES team(id), + environment character varying(255), + resource_type character varying(255), + resource_id character varying(255), + resource_action character varying(255), + status character varying(255) NOT NULL, + grant_window BIGINT NOT NULL, + grant_at timestamp without time zone, + personal_slack_message_timestamp character varying(255), + group_slack_message_timestamp character varying(255), +); \ No newline at end of file diff --git a/src/main/resources/db/migration/V1.69__Add_just_in_time_approvals_table.sql b/src/main/resources/db/migration/V1.69__Add_just_in_time_approvals_table.sql new file mode 100644 index 00000000..d303e3d6 --- /dev/null +++ b/src/main/resources/db/migration/V1.69__Add_just_in_time_approvals_table.sql @@ -0,0 +1,10 @@ +CREATE TABLE jit_approvals ( + id BIGSERIAL PRIMARY KEY, + created_at timestamp without time zone NOT NULL, + updated_at timestamp without time zone NOT NULL, + jit_id BIGINT NOT NULL REFERENCES jit_requests(id), + reviewer_id BIGINT NOT NULL REFERENCES users(id), + reviewed_at timestamp without time zone, + action character varying(255) NOT NULL, + slack_message_timestamp character varying(255), +); \ No newline at end of file diff --git a/src/main/resources/db/migration/V1.70__Add_jit_roles_privileges.sql b/src/main/resources/db/migration/V1.70__Add_jit_roles_privileges.sql new file mode 100644 index 00000000..4d8ed085 --- /dev/null +++ b/src/main/resources/db/migration/V1.70__Add_jit_roles_privileges.sql @@ -0,0 +1,2181 @@ +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AMC:cmd:.*:read'), (now(), now(), 'jit:AMC:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AMC_cmd_JITVIEWER'), (now(), now(), 'AMC_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_cmd_JITVIEWER' AND privilege.name IN ( 'jit:AMC:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:AMC:cmd:.*:read', 'jit:AMC:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AMC:prod:.*:read'), (now(), now(), 'jit:AMC:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AMC_prod_JITVIEWER'), (now(), now(), 'AMC_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_prod_JITVIEWER' AND privilege.name IN ( 'jit:AMC:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_prod_JITREVIEWER' AND privilege.name IN ( 'jit:AMC:prod:.*:read', 'jit:AMC:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AMC:dev:.*:read'), (now(), now(), 'jit:AMC:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AMC_dev_JITVIEWER'), (now(), now(), 'AMC_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_dev_JITVIEWER' AND privilege.name IN ( 'jit:AMC:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_dev_JITREVIEWER' AND privilege.name IN ( 'jit:AMC:dev:.*:read', 'jit:AMC:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AMC:qa:.*:read'), (now(), now(), 'jit:AMC:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AMC_qa_JITVIEWER'), (now(), now(), 'AMC_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_qa_JITVIEWER' AND privilege.name IN ( 'jit:AMC:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_qa_JITREVIEWER' AND privilege.name IN ( 'jit:AMC:qa:.*:read', 'jit:AMC:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AMC:perf:.*:read'), (now(), now(), 'jit:AMC:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AMC_perf_JITVIEWER'), (now(), now(), 'AMC_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_perf_JITVIEWER' AND privilege.name IN ( 'jit:AMC:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_perf_JITREVIEWER' AND privilege.name IN ( 'jit:AMC:perf:.*:read', 'jit:AMC:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AMC:uat:.*:read'), (now(), now(), 'jit:AMC:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AMC_uat_JITVIEWER'), (now(), now(), 'AMC_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_uat_JITVIEWER' AND privilege.name IN ( 'jit:AMC:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_uat_JITREVIEWER' AND privilege.name IN ( 'jit:AMC:uat:.*:read', 'jit:AMC:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AMC:data-platform-prod:.*:read'), (now(), now(), 'jit:AMC:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AMC_data-platform-prod_JITVIEWER'), (now(), now(), 'AMC_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:AMC:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:AMC:data-platform-prod:.*:read', 'jit:AMC:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AMC:data-platform-nonprod:.*:read'), (now(), now(), 'jit:AMC:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AMC_data-platform-nonprod_JITVIEWER'), (now(), now(), 'AMC_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:AMC:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:AMC:data-platform-nonprod:.*:read', 'jit:AMC:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AMC:local:.*:read'), (now(), now(), 'jit:AMC:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AMC_local_JITVIEWER'), (now(), now(), 'AMC_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_local_JITVIEWER' AND privilege.name IN ( 'jit:AMC:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_local_JITREVIEWER' AND privilege.name IN ( 'jit:AMC:local:.*:read', 'jit:AMC:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AMC:.*:.*:read'), (now(), now(), 'jit:AMC:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AMC_ALL_JITVIEWER'), (now(), now(), 'AMC_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_ALL_JITVIEWER' AND privilege.name IN ( 'jit:AMC:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AMC_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:AMC:.*:.*:read', 'jit:AMC:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:App:cmd:.*:read'), (now(), now(), 'jit:App:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'App_cmd_JITVIEWER'), (now(), now(), 'App_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_cmd_JITVIEWER' AND privilege.name IN ( 'jit:App:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:App:cmd:.*:read', 'jit:App:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:App:prod:.*:read'), (now(), now(), 'jit:App:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'App_prod_JITVIEWER'), (now(), now(), 'App_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_prod_JITVIEWER' AND privilege.name IN ( 'jit:App:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_prod_JITREVIEWER' AND privilege.name IN ( 'jit:App:prod:.*:read', 'jit:App:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:App:dev:.*:read'), (now(), now(), 'jit:App:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'App_dev_JITVIEWER'), (now(), now(), 'App_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_dev_JITVIEWER' AND privilege.name IN ( 'jit:App:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_dev_JITREVIEWER' AND privilege.name IN ( 'jit:App:dev:.*:read', 'jit:App:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:App:qa:.*:read'), (now(), now(), 'jit:App:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'App_qa_JITVIEWER'), (now(), now(), 'App_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_qa_JITVIEWER' AND privilege.name IN ( 'jit:App:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_qa_JITREVIEWER' AND privilege.name IN ( 'jit:App:qa:.*:read', 'jit:App:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:App:perf:.*:read'), (now(), now(), 'jit:App:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'App_perf_JITVIEWER'), (now(), now(), 'App_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_perf_JITVIEWER' AND privilege.name IN ( 'jit:App:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_perf_JITREVIEWER' AND privilege.name IN ( 'jit:App:perf:.*:read', 'jit:App:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:App:uat:.*:read'), (now(), now(), 'jit:App:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'App_uat_JITVIEWER'), (now(), now(), 'App_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_uat_JITVIEWER' AND privilege.name IN ( 'jit:App:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_uat_JITREVIEWER' AND privilege.name IN ( 'jit:App:uat:.*:read', 'jit:App:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:App:data-platform-prod:.*:read'), (now(), now(), 'jit:App:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'App_data-platform-prod_JITVIEWER'), (now(), now(), 'App_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:App:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:App:data-platform-prod:.*:read', 'jit:App:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:App:data-platform-nonprod:.*:read'), (now(), now(), 'jit:App:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'App_data-platform-nonprod_JITVIEWER'), (now(), now(), 'App_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:App:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:App:data-platform-nonprod:.*:read', 'jit:App:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:App:local:.*:read'), (now(), now(), 'jit:App:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'App_local_JITVIEWER'), (now(), now(), 'App_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_local_JITVIEWER' AND privilege.name IN ( 'jit:App:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_local_JITREVIEWER' AND privilege.name IN ( 'jit:App:local:.*:read', 'jit:App:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:App:.*:.*:read'), (now(), now(), 'jit:App:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'App_ALL_JITVIEWER'), (now(), now(), 'App_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_ALL_JITVIEWER' AND privilege.name IN ( 'jit:App:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'App_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:App:.*:.*:read', 'jit:App:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AppX-Bridge:cmd:.*:read'), (now(), now(), 'jit:AppX-Bridge:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AppX-Bridge_cmd_JITVIEWER'), (now(), now(), 'AppX-Bridge_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_cmd_JITVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:cmd:.*:read', 'jit:AppX-Bridge:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AppX-Bridge:prod:.*:read'), (now(), now(), 'jit:AppX-Bridge:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AppX-Bridge_prod_JITVIEWER'), (now(), now(), 'AppX-Bridge_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_prod_JITVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_prod_JITREVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:prod:.*:read', 'jit:AppX-Bridge:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AppX-Bridge:dev:.*:read'), (now(), now(), 'jit:AppX-Bridge:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AppX-Bridge_dev_JITVIEWER'), (now(), now(), 'AppX-Bridge_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_dev_JITVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_dev_JITREVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:dev:.*:read', 'jit:AppX-Bridge:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AppX-Bridge:qa:.*:read'), (now(), now(), 'jit:AppX-Bridge:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AppX-Bridge_qa_JITVIEWER'), (now(), now(), 'AppX-Bridge_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_qa_JITVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_qa_JITREVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:qa:.*:read', 'jit:AppX-Bridge:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AppX-Bridge:perf:.*:read'), (now(), now(), 'jit:AppX-Bridge:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AppX-Bridge_perf_JITVIEWER'), (now(), now(), 'AppX-Bridge_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_perf_JITVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_perf_JITREVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:perf:.*:read', 'jit:AppX-Bridge:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AppX-Bridge:uat:.*:read'), (now(), now(), 'jit:AppX-Bridge:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AppX-Bridge_uat_JITVIEWER'), (now(), now(), 'AppX-Bridge_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_uat_JITVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_uat_JITREVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:uat:.*:read', 'jit:AppX-Bridge:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AppX-Bridge:data-platform-prod:.*:read'), (now(), now(), 'jit:AppX-Bridge:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AppX-Bridge_data-platform-prod_JITVIEWER'), (now(), now(), 'AppX-Bridge_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:data-platform-prod:.*:read', 'jit:AppX-Bridge:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AppX-Bridge:data-platform-nonprod:.*:read'), (now(), now(), 'jit:AppX-Bridge:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AppX-Bridge_data-platform-nonprod_JITVIEWER'), (now(), now(), 'AppX-Bridge_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:data-platform-nonprod:.*:read', 'jit:AppX-Bridge:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AppX-Bridge:local:.*:read'), (now(), now(), 'jit:AppX-Bridge:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AppX-Bridge_local_JITVIEWER'), (now(), now(), 'AppX-Bridge_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_local_JITVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_local_JITREVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:local:.*:read', 'jit:AppX-Bridge:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:AppX-Bridge:.*:.*:read'), (now(), now(), 'jit:AppX-Bridge:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'AppX-Bridge_ALL_JITVIEWER'), (now(), now(), 'AppX-Bridge_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_ALL_JITVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'AppX-Bridge_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:AppX-Bridge:.*:.*:read', 'jit:AppX-Bridge:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Architect:cmd:.*:read'), (now(), now(), 'jit:Architect:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Architect_cmd_JITVIEWER'), (now(), now(), 'Architect_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Architect:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Architect:cmd:.*:read', 'jit:Architect:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Architect:prod:.*:read'), (now(), now(), 'jit:Architect:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Architect_prod_JITVIEWER'), (now(), now(), 'Architect_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_prod_JITVIEWER' AND privilege.name IN ( 'jit:Architect:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Architect:prod:.*:read', 'jit:Architect:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Architect:dev:.*:read'), (now(), now(), 'jit:Architect:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Architect_dev_JITVIEWER'), (now(), now(), 'Architect_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_dev_JITVIEWER' AND privilege.name IN ( 'jit:Architect:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Architect:dev:.*:read', 'jit:Architect:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Architect:qa:.*:read'), (now(), now(), 'jit:Architect:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Architect_qa_JITVIEWER'), (now(), now(), 'Architect_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_qa_JITVIEWER' AND privilege.name IN ( 'jit:Architect:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Architect:qa:.*:read', 'jit:Architect:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Architect:perf:.*:read'), (now(), now(), 'jit:Architect:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Architect_perf_JITVIEWER'), (now(), now(), 'Architect_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_perf_JITVIEWER' AND privilege.name IN ( 'jit:Architect:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Architect:perf:.*:read', 'jit:Architect:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Architect:uat:.*:read'), (now(), now(), 'jit:Architect:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Architect_uat_JITVIEWER'), (now(), now(), 'Architect_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_uat_JITVIEWER' AND privilege.name IN ( 'jit:Architect:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Architect:uat:.*:read', 'jit:Architect:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Architect:data-platform-prod:.*:read'), (now(), now(), 'jit:Architect:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Architect_data-platform-prod_JITVIEWER'), (now(), now(), 'Architect_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Architect:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Architect:data-platform-prod:.*:read', 'jit:Architect:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Architect:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Architect:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Architect_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Architect_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Architect:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Architect:data-platform-nonprod:.*:read', 'jit:Architect:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Architect:local:.*:read'), (now(), now(), 'jit:Architect:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Architect_local_JITVIEWER'), (now(), now(), 'Architect_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_local_JITVIEWER' AND privilege.name IN ( 'jit:Architect:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_local_JITREVIEWER' AND privilege.name IN ( 'jit:Architect:local:.*:read', 'jit:Architect:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Architect:.*:.*:read'), (now(), now(), 'jit:Architect:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Architect_ALL_JITVIEWER'), (now(), now(), 'Architect_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Architect:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Architect_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Architect:.*:.*:read', 'jit:Architect:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Bootcamp:cmd:.*:read'), (now(), now(), 'jit:Bootcamp:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Bootcamp_cmd_JITVIEWER'), (now(), now(), 'Bootcamp_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Bootcamp:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Bootcamp:cmd:.*:read', 'jit:Bootcamp:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Bootcamp:prod:.*:read'), (now(), now(), 'jit:Bootcamp:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Bootcamp_prod_JITVIEWER'), (now(), now(), 'Bootcamp_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_prod_JITVIEWER' AND privilege.name IN ( 'jit:Bootcamp:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Bootcamp:prod:.*:read', 'jit:Bootcamp:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Bootcamp:dev:.*:read'), (now(), now(), 'jit:Bootcamp:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Bootcamp_dev_JITVIEWER'), (now(), now(), 'Bootcamp_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_dev_JITVIEWER' AND privilege.name IN ( 'jit:Bootcamp:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Bootcamp:dev:.*:read', 'jit:Bootcamp:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Bootcamp:qa:.*:read'), (now(), now(), 'jit:Bootcamp:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Bootcamp_qa_JITVIEWER'), (now(), now(), 'Bootcamp_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_qa_JITVIEWER' AND privilege.name IN ( 'jit:Bootcamp:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Bootcamp:qa:.*:read', 'jit:Bootcamp:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Bootcamp:perf:.*:read'), (now(), now(), 'jit:Bootcamp:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Bootcamp_perf_JITVIEWER'), (now(), now(), 'Bootcamp_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_perf_JITVIEWER' AND privilege.name IN ( 'jit:Bootcamp:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Bootcamp:perf:.*:read', 'jit:Bootcamp:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Bootcamp:uat:.*:read'), (now(), now(), 'jit:Bootcamp:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Bootcamp_uat_JITVIEWER'), (now(), now(), 'Bootcamp_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_uat_JITVIEWER' AND privilege.name IN ( 'jit:Bootcamp:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Bootcamp:uat:.*:read', 'jit:Bootcamp:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Bootcamp:data-platform-prod:.*:read'), (now(), now(), 'jit:Bootcamp:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Bootcamp_data-platform-prod_JITVIEWER'), (now(), now(), 'Bootcamp_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Bootcamp:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Bootcamp:data-platform-prod:.*:read', 'jit:Bootcamp:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Bootcamp:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Bootcamp:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Bootcamp_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Bootcamp_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Bootcamp:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Bootcamp:data-platform-nonprod:.*:read', 'jit:Bootcamp:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Bootcamp:local:.*:read'), (now(), now(), 'jit:Bootcamp:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Bootcamp_local_JITVIEWER'), (now(), now(), 'Bootcamp_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_local_JITVIEWER' AND privilege.name IN ( 'jit:Bootcamp:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_local_JITREVIEWER' AND privilege.name IN ( 'jit:Bootcamp:local:.*:read', 'jit:Bootcamp:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Bootcamp:.*:.*:read'), (now(), now(), 'jit:Bootcamp:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Bootcamp_ALL_JITVIEWER'), (now(), now(), 'Bootcamp_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Bootcamp:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Bootcamp_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Bootcamp:.*:.*:read', 'jit:Bootcamp:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Borrowings:cmd:.*:read'), (now(), now(), 'jit:Borrowings:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Borrowings_cmd_JITVIEWER'), (now(), now(), 'Borrowings_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Borrowings:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Borrowings:cmd:.*:read', 'jit:Borrowings:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Borrowings:prod:.*:read'), (now(), now(), 'jit:Borrowings:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Borrowings_prod_JITVIEWER'), (now(), now(), 'Borrowings_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_prod_JITVIEWER' AND privilege.name IN ( 'jit:Borrowings:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Borrowings:prod:.*:read', 'jit:Borrowings:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Borrowings:dev:.*:read'), (now(), now(), 'jit:Borrowings:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Borrowings_dev_JITVIEWER'), (now(), now(), 'Borrowings_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_dev_JITVIEWER' AND privilege.name IN ( 'jit:Borrowings:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Borrowings:dev:.*:read', 'jit:Borrowings:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Borrowings:qa:.*:read'), (now(), now(), 'jit:Borrowings:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Borrowings_qa_JITVIEWER'), (now(), now(), 'Borrowings_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_qa_JITVIEWER' AND privilege.name IN ( 'jit:Borrowings:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Borrowings:qa:.*:read', 'jit:Borrowings:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Borrowings:perf:.*:read'), (now(), now(), 'jit:Borrowings:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Borrowings_perf_JITVIEWER'), (now(), now(), 'Borrowings_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_perf_JITVIEWER' AND privilege.name IN ( 'jit:Borrowings:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Borrowings:perf:.*:read', 'jit:Borrowings:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Borrowings:uat:.*:read'), (now(), now(), 'jit:Borrowings:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Borrowings_uat_JITVIEWER'), (now(), now(), 'Borrowings_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_uat_JITVIEWER' AND privilege.name IN ( 'jit:Borrowings:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Borrowings:uat:.*:read', 'jit:Borrowings:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Borrowings:data-platform-prod:.*:read'), (now(), now(), 'jit:Borrowings:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Borrowings_data-platform-prod_JITVIEWER'), (now(), now(), 'Borrowings_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Borrowings:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Borrowings:data-platform-prod:.*:read', 'jit:Borrowings:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Borrowings:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Borrowings:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Borrowings_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Borrowings_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Borrowings:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Borrowings:data-platform-nonprod:.*:read', 'jit:Borrowings:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Borrowings:local:.*:read'), (now(), now(), 'jit:Borrowings:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Borrowings_local_JITVIEWER'), (now(), now(), 'Borrowings_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_local_JITVIEWER' AND privilege.name IN ( 'jit:Borrowings:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_local_JITREVIEWER' AND privilege.name IN ( 'jit:Borrowings:local:.*:read', 'jit:Borrowings:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Borrowings:.*:.*:read'), (now(), now(), 'jit:Borrowings:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Borrowings_ALL_JITVIEWER'), (now(), now(), 'Borrowings_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Borrowings:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Borrowings_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Borrowings:.*:.*:read', 'jit:Borrowings:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CBP:cmd:.*:read'), (now(), now(), 'jit:CBP:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CBP_cmd_JITVIEWER'), (now(), now(), 'CBP_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_cmd_JITVIEWER' AND privilege.name IN ( 'jit:CBP:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:CBP:cmd:.*:read', 'jit:CBP:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CBP:prod:.*:read'), (now(), now(), 'jit:CBP:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CBP_prod_JITVIEWER'), (now(), now(), 'CBP_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_prod_JITVIEWER' AND privilege.name IN ( 'jit:CBP:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_prod_JITREVIEWER' AND privilege.name IN ( 'jit:CBP:prod:.*:read', 'jit:CBP:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CBP:dev:.*:read'), (now(), now(), 'jit:CBP:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CBP_dev_JITVIEWER'), (now(), now(), 'CBP_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_dev_JITVIEWER' AND privilege.name IN ( 'jit:CBP:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_dev_JITREVIEWER' AND privilege.name IN ( 'jit:CBP:dev:.*:read', 'jit:CBP:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CBP:qa:.*:read'), (now(), now(), 'jit:CBP:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CBP_qa_JITVIEWER'), (now(), now(), 'CBP_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_qa_JITVIEWER' AND privilege.name IN ( 'jit:CBP:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_qa_JITREVIEWER' AND privilege.name IN ( 'jit:CBP:qa:.*:read', 'jit:CBP:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CBP:perf:.*:read'), (now(), now(), 'jit:CBP:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CBP_perf_JITVIEWER'), (now(), now(), 'CBP_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_perf_JITVIEWER' AND privilege.name IN ( 'jit:CBP:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_perf_JITREVIEWER' AND privilege.name IN ( 'jit:CBP:perf:.*:read', 'jit:CBP:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CBP:uat:.*:read'), (now(), now(), 'jit:CBP:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CBP_uat_JITVIEWER'), (now(), now(), 'CBP_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_uat_JITVIEWER' AND privilege.name IN ( 'jit:CBP:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_uat_JITREVIEWER' AND privilege.name IN ( 'jit:CBP:uat:.*:read', 'jit:CBP:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CBP:data-platform-prod:.*:read'), (now(), now(), 'jit:CBP:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CBP_data-platform-prod_JITVIEWER'), (now(), now(), 'CBP_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:CBP:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:CBP:data-platform-prod:.*:read', 'jit:CBP:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CBP:data-platform-nonprod:.*:read'), (now(), now(), 'jit:CBP:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CBP_data-platform-nonprod_JITVIEWER'), (now(), now(), 'CBP_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:CBP:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:CBP:data-platform-nonprod:.*:read', 'jit:CBP:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CBP:local:.*:read'), (now(), now(), 'jit:CBP:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CBP_local_JITVIEWER'), (now(), now(), 'CBP_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_local_JITVIEWER' AND privilege.name IN ( 'jit:CBP:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_local_JITREVIEWER' AND privilege.name IN ( 'jit:CBP:local:.*:read', 'jit:CBP:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CBP:.*:.*:read'), (now(), now(), 'jit:CBP:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CBP_ALL_JITVIEWER'), (now(), now(), 'CBP_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_ALL_JITVIEWER' AND privilege.name IN ( 'jit:CBP:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CBP_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:CBP:.*:.*:read', 'jit:CBP:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Claims:cmd:.*:read'), (now(), now(), 'jit:Claims:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Claims_cmd_JITVIEWER'), (now(), now(), 'Claims_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Claims:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Claims:cmd:.*:read', 'jit:Claims:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Claims:prod:.*:read'), (now(), now(), 'jit:Claims:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Claims_prod_JITVIEWER'), (now(), now(), 'Claims_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_prod_JITVIEWER' AND privilege.name IN ( 'jit:Claims:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Claims:prod:.*:read', 'jit:Claims:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Claims:dev:.*:read'), (now(), now(), 'jit:Claims:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Claims_dev_JITVIEWER'), (now(), now(), 'Claims_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_dev_JITVIEWER' AND privilege.name IN ( 'jit:Claims:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Claims:dev:.*:read', 'jit:Claims:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Claims:qa:.*:read'), (now(), now(), 'jit:Claims:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Claims_qa_JITVIEWER'), (now(), now(), 'Claims_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_qa_JITVIEWER' AND privilege.name IN ( 'jit:Claims:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Claims:qa:.*:read', 'jit:Claims:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Claims:perf:.*:read'), (now(), now(), 'jit:Claims:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Claims_perf_JITVIEWER'), (now(), now(), 'Claims_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_perf_JITVIEWER' AND privilege.name IN ( 'jit:Claims:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Claims:perf:.*:read', 'jit:Claims:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Claims:uat:.*:read'), (now(), now(), 'jit:Claims:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Claims_uat_JITVIEWER'), (now(), now(), 'Claims_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_uat_JITVIEWER' AND privilege.name IN ( 'jit:Claims:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Claims:uat:.*:read', 'jit:Claims:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Claims:data-platform-prod:.*:read'), (now(), now(), 'jit:Claims:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Claims_data-platform-prod_JITVIEWER'), (now(), now(), 'Claims_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Claims:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Claims:data-platform-prod:.*:read', 'jit:Claims:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Claims:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Claims:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Claims_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Claims_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Claims:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Claims:data-platform-nonprod:.*:read', 'jit:Claims:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Claims:local:.*:read'), (now(), now(), 'jit:Claims:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Claims_local_JITVIEWER'), (now(), now(), 'Claims_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_local_JITVIEWER' AND privilege.name IN ( 'jit:Claims:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_local_JITREVIEWER' AND privilege.name IN ( 'jit:Claims:local:.*:read', 'jit:Claims:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Claims:.*:.*:read'), (now(), now(), 'jit:Claims:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Claims_ALL_JITVIEWER'), (now(), now(), 'Claims_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Claims:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Claims_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Claims:.*:.*:read', 'jit:Claims:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Co-Lending:cmd:.*:read'), (now(), now(), 'jit:Co-Lending:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Co-Lending_cmd_JITVIEWER'), (now(), now(), 'Co-Lending_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Co-Lending:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Co-Lending:cmd:.*:read', 'jit:Co-Lending:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Co-Lending:prod:.*:read'), (now(), now(), 'jit:Co-Lending:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Co-Lending_prod_JITVIEWER'), (now(), now(), 'Co-Lending_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_prod_JITVIEWER' AND privilege.name IN ( 'jit:Co-Lending:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Co-Lending:prod:.*:read', 'jit:Co-Lending:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Co-Lending:dev:.*:read'), (now(), now(), 'jit:Co-Lending:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Co-Lending_dev_JITVIEWER'), (now(), now(), 'Co-Lending_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_dev_JITVIEWER' AND privilege.name IN ( 'jit:Co-Lending:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Co-Lending:dev:.*:read', 'jit:Co-Lending:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Co-Lending:qa:.*:read'), (now(), now(), 'jit:Co-Lending:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Co-Lending_qa_JITVIEWER'), (now(), now(), 'Co-Lending_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_qa_JITVIEWER' AND privilege.name IN ( 'jit:Co-Lending:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Co-Lending:qa:.*:read', 'jit:Co-Lending:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Co-Lending:perf:.*:read'), (now(), now(), 'jit:Co-Lending:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Co-Lending_perf_JITVIEWER'), (now(), now(), 'Co-Lending_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_perf_JITVIEWER' AND privilege.name IN ( 'jit:Co-Lending:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Co-Lending:perf:.*:read', 'jit:Co-Lending:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Co-Lending:uat:.*:read'), (now(), now(), 'jit:Co-Lending:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Co-Lending_uat_JITVIEWER'), (now(), now(), 'Co-Lending_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_uat_JITVIEWER' AND privilege.name IN ( 'jit:Co-Lending:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Co-Lending:uat:.*:read', 'jit:Co-Lending:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Co-Lending:data-platform-prod:.*:read'), (now(), now(), 'jit:Co-Lending:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Co-Lending_data-platform-prod_JITVIEWER'), (now(), now(), 'Co-Lending_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Co-Lending:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Co-Lending:data-platform-prod:.*:read', 'jit:Co-Lending:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Co-Lending:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Co-Lending:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Co-Lending_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Co-Lending_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Co-Lending:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Co-Lending:data-platform-nonprod:.*:read', 'jit:Co-Lending:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Co-Lending:local:.*:read'), (now(), now(), 'jit:Co-Lending:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Co-Lending_local_JITVIEWER'), (now(), now(), 'Co-Lending_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_local_JITVIEWER' AND privilege.name IN ( 'jit:Co-Lending:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_local_JITREVIEWER' AND privilege.name IN ( 'jit:Co-Lending:local:.*:read', 'jit:Co-Lending:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Co-Lending:.*:.*:read'), (now(), now(), 'jit:Co-Lending:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Co-Lending_ALL_JITVIEWER'), (now(), now(), 'Co-Lending_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Co-Lending:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Co-Lending_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Co-Lending:.*:.*:read', 'jit:Co-Lending:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Collections:cmd:.*:read'), (now(), now(), 'jit:Collections:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Collections_cmd_JITVIEWER'), (now(), now(), 'Collections_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Collections:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Collections:cmd:.*:read', 'jit:Collections:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Collections:prod:.*:read'), (now(), now(), 'jit:Collections:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Collections_prod_JITVIEWER'), (now(), now(), 'Collections_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_prod_JITVIEWER' AND privilege.name IN ( 'jit:Collections:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Collections:prod:.*:read', 'jit:Collections:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Collections:dev:.*:read'), (now(), now(), 'jit:Collections:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Collections_dev_JITVIEWER'), (now(), now(), 'Collections_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_dev_JITVIEWER' AND privilege.name IN ( 'jit:Collections:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Collections:dev:.*:read', 'jit:Collections:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Collections:qa:.*:read'), (now(), now(), 'jit:Collections:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Collections_qa_JITVIEWER'), (now(), now(), 'Collections_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_qa_JITVIEWER' AND privilege.name IN ( 'jit:Collections:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Collections:qa:.*:read', 'jit:Collections:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Collections:perf:.*:read'), (now(), now(), 'jit:Collections:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Collections_perf_JITVIEWER'), (now(), now(), 'Collections_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_perf_JITVIEWER' AND privilege.name IN ( 'jit:Collections:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Collections:perf:.*:read', 'jit:Collections:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Collections:uat:.*:read'), (now(), now(), 'jit:Collections:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Collections_uat_JITVIEWER'), (now(), now(), 'Collections_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_uat_JITVIEWER' AND privilege.name IN ( 'jit:Collections:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Collections:uat:.*:read', 'jit:Collections:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Collections:data-platform-prod:.*:read'), (now(), now(), 'jit:Collections:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Collections_data-platform-prod_JITVIEWER'), (now(), now(), 'Collections_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Collections:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Collections:data-platform-prod:.*:read', 'jit:Collections:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Collections:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Collections:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Collections_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Collections_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Collections:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Collections:data-platform-nonprod:.*:read', 'jit:Collections:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Collections:local:.*:read'), (now(), now(), 'jit:Collections:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Collections_local_JITVIEWER'), (now(), now(), 'Collections_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_local_JITVIEWER' AND privilege.name IN ( 'jit:Collections:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_local_JITREVIEWER' AND privilege.name IN ( 'jit:Collections:local:.*:read', 'jit:Collections:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Collections:.*:.*:read'), (now(), now(), 'jit:Collections:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Collections_ALL_JITVIEWER'), (now(), now(), 'Collections_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Collections:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Collections_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Collections:.*:.*:read', 'jit:Collections:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Communication:cmd:.*:read'), (now(), now(), 'jit:Communication:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Communication_cmd_JITVIEWER'), (now(), now(), 'Communication_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Communication:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Communication:cmd:.*:read', 'jit:Communication:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Communication:prod:.*:read'), (now(), now(), 'jit:Communication:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Communication_prod_JITVIEWER'), (now(), now(), 'Communication_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_prod_JITVIEWER' AND privilege.name IN ( 'jit:Communication:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Communication:prod:.*:read', 'jit:Communication:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Communication:dev:.*:read'), (now(), now(), 'jit:Communication:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Communication_dev_JITVIEWER'), (now(), now(), 'Communication_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_dev_JITVIEWER' AND privilege.name IN ( 'jit:Communication:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Communication:dev:.*:read', 'jit:Communication:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Communication:qa:.*:read'), (now(), now(), 'jit:Communication:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Communication_qa_JITVIEWER'), (now(), now(), 'Communication_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_qa_JITVIEWER' AND privilege.name IN ( 'jit:Communication:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Communication:qa:.*:read', 'jit:Communication:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Communication:perf:.*:read'), (now(), now(), 'jit:Communication:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Communication_perf_JITVIEWER'), (now(), now(), 'Communication_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_perf_JITVIEWER' AND privilege.name IN ( 'jit:Communication:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Communication:perf:.*:read', 'jit:Communication:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Communication:uat:.*:read'), (now(), now(), 'jit:Communication:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Communication_uat_JITVIEWER'), (now(), now(), 'Communication_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_uat_JITVIEWER' AND privilege.name IN ( 'jit:Communication:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Communication:uat:.*:read', 'jit:Communication:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Communication:data-platform-prod:.*:read'), (now(), now(), 'jit:Communication:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Communication_data-platform-prod_JITVIEWER'), (now(), now(), 'Communication_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Communication:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Communication:data-platform-prod:.*:read', 'jit:Communication:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Communication:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Communication:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Communication_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Communication_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Communication:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Communication:data-platform-nonprod:.*:read', 'jit:Communication:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Communication:local:.*:read'), (now(), now(), 'jit:Communication:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Communication_local_JITVIEWER'), (now(), now(), 'Communication_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_local_JITVIEWER' AND privilege.name IN ( 'jit:Communication:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_local_JITREVIEWER' AND privilege.name IN ( 'jit:Communication:local:.*:read', 'jit:Communication:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Communication:.*:.*:read'), (now(), now(), 'jit:Communication:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Communication_ALL_JITVIEWER'), (now(), now(), 'Communication_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Communication:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Communication_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Communication:.*:.*:read', 'jit:Communication:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Cosmos:cmd:.*:read'), (now(), now(), 'jit:Cosmos:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Cosmos_cmd_JITVIEWER'), (now(), now(), 'Cosmos_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Cosmos:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Cosmos:cmd:.*:read', 'jit:Cosmos:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Cosmos:prod:.*:read'), (now(), now(), 'jit:Cosmos:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Cosmos_prod_JITVIEWER'), (now(), now(), 'Cosmos_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_prod_JITVIEWER' AND privilege.name IN ( 'jit:Cosmos:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Cosmos:prod:.*:read', 'jit:Cosmos:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Cosmos:dev:.*:read'), (now(), now(), 'jit:Cosmos:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Cosmos_dev_JITVIEWER'), (now(), now(), 'Cosmos_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_dev_JITVIEWER' AND privilege.name IN ( 'jit:Cosmos:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Cosmos:dev:.*:read', 'jit:Cosmos:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Cosmos:qa:.*:read'), (now(), now(), 'jit:Cosmos:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Cosmos_qa_JITVIEWER'), (now(), now(), 'Cosmos_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_qa_JITVIEWER' AND privilege.name IN ( 'jit:Cosmos:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Cosmos:qa:.*:read', 'jit:Cosmos:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Cosmos:perf:.*:read'), (now(), now(), 'jit:Cosmos:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Cosmos_perf_JITVIEWER'), (now(), now(), 'Cosmos_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_perf_JITVIEWER' AND privilege.name IN ( 'jit:Cosmos:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Cosmos:perf:.*:read', 'jit:Cosmos:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Cosmos:uat:.*:read'), (now(), now(), 'jit:Cosmos:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Cosmos_uat_JITVIEWER'), (now(), now(), 'Cosmos_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_uat_JITVIEWER' AND privilege.name IN ( 'jit:Cosmos:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Cosmos:uat:.*:read', 'jit:Cosmos:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Cosmos:data-platform-prod:.*:read'), (now(), now(), 'jit:Cosmos:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Cosmos_data-platform-prod_JITVIEWER'), (now(), now(), 'Cosmos_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Cosmos:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Cosmos:data-platform-prod:.*:read', 'jit:Cosmos:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Cosmos:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Cosmos:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Cosmos_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Cosmos_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Cosmos:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Cosmos:data-platform-nonprod:.*:read', 'jit:Cosmos:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Cosmos:local:.*:read'), (now(), now(), 'jit:Cosmos:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Cosmos_local_JITVIEWER'), (now(), now(), 'Cosmos_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_local_JITVIEWER' AND privilege.name IN ( 'jit:Cosmos:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_local_JITREVIEWER' AND privilege.name IN ( 'jit:Cosmos:local:.*:read', 'jit:Cosmos:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Cosmos:.*:.*:read'), (now(), now(), 'jit:Cosmos:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Cosmos_ALL_JITVIEWER'), (now(), now(), 'Cosmos_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Cosmos:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Cosmos_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Cosmos:.*:.*:read', 'jit:Cosmos:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CRM:cmd:.*:read'), (now(), now(), 'jit:CRM:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CRM_cmd_JITVIEWER'), (now(), now(), 'CRM_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_cmd_JITVIEWER' AND privilege.name IN ( 'jit:CRM:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:CRM:cmd:.*:read', 'jit:CRM:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CRM:prod:.*:read'), (now(), now(), 'jit:CRM:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CRM_prod_JITVIEWER'), (now(), now(), 'CRM_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_prod_JITVIEWER' AND privilege.name IN ( 'jit:CRM:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_prod_JITREVIEWER' AND privilege.name IN ( 'jit:CRM:prod:.*:read', 'jit:CRM:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CRM:dev:.*:read'), (now(), now(), 'jit:CRM:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CRM_dev_JITVIEWER'), (now(), now(), 'CRM_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_dev_JITVIEWER' AND privilege.name IN ( 'jit:CRM:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_dev_JITREVIEWER' AND privilege.name IN ( 'jit:CRM:dev:.*:read', 'jit:CRM:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CRM:qa:.*:read'), (now(), now(), 'jit:CRM:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CRM_qa_JITVIEWER'), (now(), now(), 'CRM_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_qa_JITVIEWER' AND privilege.name IN ( 'jit:CRM:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_qa_JITREVIEWER' AND privilege.name IN ( 'jit:CRM:qa:.*:read', 'jit:CRM:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CRM:perf:.*:read'), (now(), now(), 'jit:CRM:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CRM_perf_JITVIEWER'), (now(), now(), 'CRM_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_perf_JITVIEWER' AND privilege.name IN ( 'jit:CRM:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_perf_JITREVIEWER' AND privilege.name IN ( 'jit:CRM:perf:.*:read', 'jit:CRM:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CRM:uat:.*:read'), (now(), now(), 'jit:CRM:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CRM_uat_JITVIEWER'), (now(), now(), 'CRM_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_uat_JITVIEWER' AND privilege.name IN ( 'jit:CRM:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_uat_JITREVIEWER' AND privilege.name IN ( 'jit:CRM:uat:.*:read', 'jit:CRM:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CRM:data-platform-prod:.*:read'), (now(), now(), 'jit:CRM:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CRM_data-platform-prod_JITVIEWER'), (now(), now(), 'CRM_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:CRM:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:CRM:data-platform-prod:.*:read', 'jit:CRM:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CRM:data-platform-nonprod:.*:read'), (now(), now(), 'jit:CRM:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CRM_data-platform-nonprod_JITVIEWER'), (now(), now(), 'CRM_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:CRM:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:CRM:data-platform-nonprod:.*:read', 'jit:CRM:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CRM:local:.*:read'), (now(), now(), 'jit:CRM:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CRM_local_JITVIEWER'), (now(), now(), 'CRM_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_local_JITVIEWER' AND privilege.name IN ( 'jit:CRM:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_local_JITREVIEWER' AND privilege.name IN ( 'jit:CRM:local:.*:read', 'jit:CRM:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:CRM:.*:.*:read'), (now(), now(), 'jit:CRM:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'CRM_ALL_JITVIEWER'), (now(), now(), 'CRM_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_ALL_JITVIEWER' AND privilege.name IN ( 'jit:CRM:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'CRM_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:CRM:.*:.*:read', 'jit:CRM:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataPlatform:cmd:.*:read'), (now(), now(), 'jit:DataPlatform:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataPlatform_cmd_JITVIEWER'), (now(), now(), 'DataPlatform_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_cmd_JITVIEWER' AND privilege.name IN ( 'jit:DataPlatform:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:DataPlatform:cmd:.*:read', 'jit:DataPlatform:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataPlatform:prod:.*:read'), (now(), now(), 'jit:DataPlatform:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataPlatform_prod_JITVIEWER'), (now(), now(), 'DataPlatform_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_prod_JITVIEWER' AND privilege.name IN ( 'jit:DataPlatform:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_prod_JITREVIEWER' AND privilege.name IN ( 'jit:DataPlatform:prod:.*:read', 'jit:DataPlatform:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataPlatform:dev:.*:read'), (now(), now(), 'jit:DataPlatform:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataPlatform_dev_JITVIEWER'), (now(), now(), 'DataPlatform_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_dev_JITVIEWER' AND privilege.name IN ( 'jit:DataPlatform:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_dev_JITREVIEWER' AND privilege.name IN ( 'jit:DataPlatform:dev:.*:read', 'jit:DataPlatform:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataPlatform:qa:.*:read'), (now(), now(), 'jit:DataPlatform:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataPlatform_qa_JITVIEWER'), (now(), now(), 'DataPlatform_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_qa_JITVIEWER' AND privilege.name IN ( 'jit:DataPlatform:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_qa_JITREVIEWER' AND privilege.name IN ( 'jit:DataPlatform:qa:.*:read', 'jit:DataPlatform:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataPlatform:perf:.*:read'), (now(), now(), 'jit:DataPlatform:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataPlatform_perf_JITVIEWER'), (now(), now(), 'DataPlatform_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_perf_JITVIEWER' AND privilege.name IN ( 'jit:DataPlatform:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_perf_JITREVIEWER' AND privilege.name IN ( 'jit:DataPlatform:perf:.*:read', 'jit:DataPlatform:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataPlatform:uat:.*:read'), (now(), now(), 'jit:DataPlatform:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataPlatform_uat_JITVIEWER'), (now(), now(), 'DataPlatform_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_uat_JITVIEWER' AND privilege.name IN ( 'jit:DataPlatform:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_uat_JITREVIEWER' AND privilege.name IN ( 'jit:DataPlatform:uat:.*:read', 'jit:DataPlatform:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataPlatform:data-platform-prod:.*:read'), (now(), now(), 'jit:DataPlatform:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataPlatform_data-platform-prod_JITVIEWER'), (now(), now(), 'DataPlatform_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:DataPlatform:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:DataPlatform:data-platform-prod:.*:read', 'jit:DataPlatform:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataPlatform:data-platform-nonprod:.*:read'), (now(), now(), 'jit:DataPlatform:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataPlatform_data-platform-nonprod_JITVIEWER'), (now(), now(), 'DataPlatform_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:DataPlatform:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:DataPlatform:data-platform-nonprod:.*:read', 'jit:DataPlatform:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataPlatform:local:.*:read'), (now(), now(), 'jit:DataPlatform:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataPlatform_local_JITVIEWER'), (now(), now(), 'DataPlatform_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_local_JITVIEWER' AND privilege.name IN ( 'jit:DataPlatform:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_local_JITREVIEWER' AND privilege.name IN ( 'jit:DataPlatform:local:.*:read', 'jit:DataPlatform:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataPlatform:.*:.*:read'), (now(), now(), 'jit:DataPlatform:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataPlatform_ALL_JITVIEWER'), (now(), now(), 'DataPlatform_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_ALL_JITVIEWER' AND privilege.name IN ( 'jit:DataPlatform:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataPlatform_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:DataPlatform:.*:.*:read', 'jit:DataPlatform:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataScience:cmd:.*:read'), (now(), now(), 'jit:DataScience:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataScience_cmd_JITVIEWER'), (now(), now(), 'DataScience_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_cmd_JITVIEWER' AND privilege.name IN ( 'jit:DataScience:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:DataScience:cmd:.*:read', 'jit:DataScience:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataScience:prod:.*:read'), (now(), now(), 'jit:DataScience:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataScience_prod_JITVIEWER'), (now(), now(), 'DataScience_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_prod_JITVIEWER' AND privilege.name IN ( 'jit:DataScience:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_prod_JITREVIEWER' AND privilege.name IN ( 'jit:DataScience:prod:.*:read', 'jit:DataScience:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataScience:dev:.*:read'), (now(), now(), 'jit:DataScience:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataScience_dev_JITVIEWER'), (now(), now(), 'DataScience_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_dev_JITVIEWER' AND privilege.name IN ( 'jit:DataScience:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_dev_JITREVIEWER' AND privilege.name IN ( 'jit:DataScience:dev:.*:read', 'jit:DataScience:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataScience:qa:.*:read'), (now(), now(), 'jit:DataScience:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataScience_qa_JITVIEWER'), (now(), now(), 'DataScience_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_qa_JITVIEWER' AND privilege.name IN ( 'jit:DataScience:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_qa_JITREVIEWER' AND privilege.name IN ( 'jit:DataScience:qa:.*:read', 'jit:DataScience:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataScience:perf:.*:read'), (now(), now(), 'jit:DataScience:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataScience_perf_JITVIEWER'), (now(), now(), 'DataScience_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_perf_JITVIEWER' AND privilege.name IN ( 'jit:DataScience:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_perf_JITREVIEWER' AND privilege.name IN ( 'jit:DataScience:perf:.*:read', 'jit:DataScience:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataScience:uat:.*:read'), (now(), now(), 'jit:DataScience:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataScience_uat_JITVIEWER'), (now(), now(), 'DataScience_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_uat_JITVIEWER' AND privilege.name IN ( 'jit:DataScience:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_uat_JITREVIEWER' AND privilege.name IN ( 'jit:DataScience:uat:.*:read', 'jit:DataScience:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataScience:data-platform-prod:.*:read'), (now(), now(), 'jit:DataScience:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataScience_data-platform-prod_JITVIEWER'), (now(), now(), 'DataScience_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:DataScience:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:DataScience:data-platform-prod:.*:read', 'jit:DataScience:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataScience:data-platform-nonprod:.*:read'), (now(), now(), 'jit:DataScience:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataScience_data-platform-nonprod_JITVIEWER'), (now(), now(), 'DataScience_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:DataScience:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:DataScience:data-platform-nonprod:.*:read', 'jit:DataScience:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataScience:local:.*:read'), (now(), now(), 'jit:DataScience:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataScience_local_JITVIEWER'), (now(), now(), 'DataScience_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_local_JITVIEWER' AND privilege.name IN ( 'jit:DataScience:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_local_JITREVIEWER' AND privilege.name IN ( 'jit:DataScience:local:.*:read', 'jit:DataScience:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:DataScience:.*:.*:read'), (now(), now(), 'jit:DataScience:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'DataScience_ALL_JITVIEWER'), (now(), now(), 'DataScience_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_ALL_JITVIEWER' AND privilege.name IN ( 'jit:DataScience:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'DataScience_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:DataScience:.*:.*:read', 'jit:DataScience:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Digital-Gold:cmd:.*:read'), (now(), now(), 'jit:Digital-Gold:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Digital-Gold_cmd_JITVIEWER'), (now(), now(), 'Digital-Gold_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:cmd:.*:read', 'jit:Digital-Gold:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Digital-Gold:prod:.*:read'), (now(), now(), 'jit:Digital-Gold:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Digital-Gold_prod_JITVIEWER'), (now(), now(), 'Digital-Gold_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_prod_JITVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:prod:.*:read', 'jit:Digital-Gold:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Digital-Gold:dev:.*:read'), (now(), now(), 'jit:Digital-Gold:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Digital-Gold_dev_JITVIEWER'), (now(), now(), 'Digital-Gold_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_dev_JITVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:dev:.*:read', 'jit:Digital-Gold:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Digital-Gold:qa:.*:read'), (now(), now(), 'jit:Digital-Gold:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Digital-Gold_qa_JITVIEWER'), (now(), now(), 'Digital-Gold_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_qa_JITVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:qa:.*:read', 'jit:Digital-Gold:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Digital-Gold:perf:.*:read'), (now(), now(), 'jit:Digital-Gold:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Digital-Gold_perf_JITVIEWER'), (now(), now(), 'Digital-Gold_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_perf_JITVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:perf:.*:read', 'jit:Digital-Gold:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Digital-Gold:uat:.*:read'), (now(), now(), 'jit:Digital-Gold:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Digital-Gold_uat_JITVIEWER'), (now(), now(), 'Digital-Gold_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_uat_JITVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:uat:.*:read', 'jit:Digital-Gold:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Digital-Gold:data-platform-prod:.*:read'), (now(), now(), 'jit:Digital-Gold:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Digital-Gold_data-platform-prod_JITVIEWER'), (now(), now(), 'Digital-Gold_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:data-platform-prod:.*:read', 'jit:Digital-Gold:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Digital-Gold:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Digital-Gold:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Digital-Gold_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Digital-Gold_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:data-platform-nonprod:.*:read', 'jit:Digital-Gold:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Digital-Gold:local:.*:read'), (now(), now(), 'jit:Digital-Gold:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Digital-Gold_local_JITVIEWER'), (now(), now(), 'Digital-Gold_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_local_JITVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_local_JITREVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:local:.*:read', 'jit:Digital-Gold:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Digital-Gold:.*:.*:read'), (now(), now(), 'jit:Digital-Gold:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Digital-Gold_ALL_JITVIEWER'), (now(), now(), 'Digital-Gold_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Digital-Gold_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Digital-Gold:.*:.*:read', 'jit:Digital-Gold:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Edge:cmd:.*:read'), (now(), now(), 'jit:Edge:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Edge_cmd_JITVIEWER'), (now(), now(), 'Edge_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Edge:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Edge:cmd:.*:read', 'jit:Edge:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Edge:prod:.*:read'), (now(), now(), 'jit:Edge:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Edge_prod_JITVIEWER'), (now(), now(), 'Edge_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_prod_JITVIEWER' AND privilege.name IN ( 'jit:Edge:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Edge:prod:.*:read', 'jit:Edge:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Edge:dev:.*:read'), (now(), now(), 'jit:Edge:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Edge_dev_JITVIEWER'), (now(), now(), 'Edge_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_dev_JITVIEWER' AND privilege.name IN ( 'jit:Edge:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Edge:dev:.*:read', 'jit:Edge:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Edge:qa:.*:read'), (now(), now(), 'jit:Edge:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Edge_qa_JITVIEWER'), (now(), now(), 'Edge_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_qa_JITVIEWER' AND privilege.name IN ( 'jit:Edge:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Edge:qa:.*:read', 'jit:Edge:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Edge:perf:.*:read'), (now(), now(), 'jit:Edge:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Edge_perf_JITVIEWER'), (now(), now(), 'Edge_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_perf_JITVIEWER' AND privilege.name IN ( 'jit:Edge:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Edge:perf:.*:read', 'jit:Edge:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Edge:uat:.*:read'), (now(), now(), 'jit:Edge:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Edge_uat_JITVIEWER'), (now(), now(), 'Edge_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_uat_JITVIEWER' AND privilege.name IN ( 'jit:Edge:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Edge:uat:.*:read', 'jit:Edge:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Edge:data-platform-prod:.*:read'), (now(), now(), 'jit:Edge:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Edge_data-platform-prod_JITVIEWER'), (now(), now(), 'Edge_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Edge:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Edge:data-platform-prod:.*:read', 'jit:Edge:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Edge:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Edge:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Edge_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Edge_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Edge:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Edge:data-platform-nonprod:.*:read', 'jit:Edge:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Edge:local:.*:read'), (now(), now(), 'jit:Edge:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Edge_local_JITVIEWER'), (now(), now(), 'Edge_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_local_JITVIEWER' AND privilege.name IN ( 'jit:Edge:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_local_JITREVIEWER' AND privilege.name IN ( 'jit:Edge:local:.*:read', 'jit:Edge:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Edge:.*:.*:read'), (now(), now(), 'jit:Edge:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Edge_ALL_JITVIEWER'), (now(), now(), 'Edge_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Edge:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Edge_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Edge:.*:.*:read', 'jit:Edge:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Frameworks:cmd:.*:read'), (now(), now(), 'jit:Frameworks:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Frameworks_cmd_JITVIEWER'), (now(), now(), 'Frameworks_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Frameworks:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Frameworks:cmd:.*:read', 'jit:Frameworks:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Frameworks:prod:.*:read'), (now(), now(), 'jit:Frameworks:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Frameworks_prod_JITVIEWER'), (now(), now(), 'Frameworks_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_prod_JITVIEWER' AND privilege.name IN ( 'jit:Frameworks:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Frameworks:prod:.*:read', 'jit:Frameworks:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Frameworks:dev:.*:read'), (now(), now(), 'jit:Frameworks:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Frameworks_dev_JITVIEWER'), (now(), now(), 'Frameworks_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_dev_JITVIEWER' AND privilege.name IN ( 'jit:Frameworks:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Frameworks:dev:.*:read', 'jit:Frameworks:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Frameworks:qa:.*:read'), (now(), now(), 'jit:Frameworks:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Frameworks_qa_JITVIEWER'), (now(), now(), 'Frameworks_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_qa_JITVIEWER' AND privilege.name IN ( 'jit:Frameworks:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Frameworks:qa:.*:read', 'jit:Frameworks:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Frameworks:perf:.*:read'), (now(), now(), 'jit:Frameworks:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Frameworks_perf_JITVIEWER'), (now(), now(), 'Frameworks_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_perf_JITVIEWER' AND privilege.name IN ( 'jit:Frameworks:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Frameworks:perf:.*:read', 'jit:Frameworks:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Frameworks:uat:.*:read'), (now(), now(), 'jit:Frameworks:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Frameworks_uat_JITVIEWER'), (now(), now(), 'Frameworks_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_uat_JITVIEWER' AND privilege.name IN ( 'jit:Frameworks:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Frameworks:uat:.*:read', 'jit:Frameworks:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Frameworks:data-platform-prod:.*:read'), (now(), now(), 'jit:Frameworks:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Frameworks_data-platform-prod_JITVIEWER'), (now(), now(), 'Frameworks_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Frameworks:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Frameworks:data-platform-prod:.*:read', 'jit:Frameworks:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Frameworks:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Frameworks:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Frameworks_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Frameworks_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Frameworks:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Frameworks:data-platform-nonprod:.*:read', 'jit:Frameworks:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Frameworks:local:.*:read'), (now(), now(), 'jit:Frameworks:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Frameworks_local_JITVIEWER'), (now(), now(), 'Frameworks_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_local_JITVIEWER' AND privilege.name IN ( 'jit:Frameworks:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_local_JITREVIEWER' AND privilege.name IN ( 'jit:Frameworks:local:.*:read', 'jit:Frameworks:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Frameworks:.*:.*:read'), (now(), now(), 'jit:Frameworks:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Frameworks_ALL_JITVIEWER'), (now(), now(), 'Frameworks_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Frameworks:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Frameworks_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Frameworks:.*:.*:read', 'jit:Frameworks:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Generative-AI:cmd:.*:read'), (now(), now(), 'jit:Generative-AI:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Generative-AI_cmd_JITVIEWER'), (now(), now(), 'Generative-AI_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Generative-AI:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Generative-AI:cmd:.*:read', 'jit:Generative-AI:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Generative-AI:prod:.*:read'), (now(), now(), 'jit:Generative-AI:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Generative-AI_prod_JITVIEWER'), (now(), now(), 'Generative-AI_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_prod_JITVIEWER' AND privilege.name IN ( 'jit:Generative-AI:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Generative-AI:prod:.*:read', 'jit:Generative-AI:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Generative-AI:dev:.*:read'), (now(), now(), 'jit:Generative-AI:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Generative-AI_dev_JITVIEWER'), (now(), now(), 'Generative-AI_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_dev_JITVIEWER' AND privilege.name IN ( 'jit:Generative-AI:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Generative-AI:dev:.*:read', 'jit:Generative-AI:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Generative-AI:qa:.*:read'), (now(), now(), 'jit:Generative-AI:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Generative-AI_qa_JITVIEWER'), (now(), now(), 'Generative-AI_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_qa_JITVIEWER' AND privilege.name IN ( 'jit:Generative-AI:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Generative-AI:qa:.*:read', 'jit:Generative-AI:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Generative-AI:perf:.*:read'), (now(), now(), 'jit:Generative-AI:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Generative-AI_perf_JITVIEWER'), (now(), now(), 'Generative-AI_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_perf_JITVIEWER' AND privilege.name IN ( 'jit:Generative-AI:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Generative-AI:perf:.*:read', 'jit:Generative-AI:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Generative-AI:uat:.*:read'), (now(), now(), 'jit:Generative-AI:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Generative-AI_uat_JITVIEWER'), (now(), now(), 'Generative-AI_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_uat_JITVIEWER' AND privilege.name IN ( 'jit:Generative-AI:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Generative-AI:uat:.*:read', 'jit:Generative-AI:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Generative-AI:data-platform-prod:.*:read'), (now(), now(), 'jit:Generative-AI:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Generative-AI_data-platform-prod_JITVIEWER'), (now(), now(), 'Generative-AI_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Generative-AI:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Generative-AI:data-platform-prod:.*:read', 'jit:Generative-AI:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Generative-AI:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Generative-AI:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Generative-AI_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Generative-AI_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Generative-AI:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Generative-AI:data-platform-nonprod:.*:read', 'jit:Generative-AI:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Generative-AI:local:.*:read'), (now(), now(), 'jit:Generative-AI:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Generative-AI_local_JITVIEWER'), (now(), now(), 'Generative-AI_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_local_JITVIEWER' AND privilege.name IN ( 'jit:Generative-AI:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_local_JITREVIEWER' AND privilege.name IN ( 'jit:Generative-AI:local:.*:read', 'jit:Generative-AI:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Generative-AI:.*:.*:read'), (now(), now(), 'jit:Generative-AI:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Generative-AI_ALL_JITVIEWER'), (now(), now(), 'Generative-AI_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Generative-AI:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Generative-AI_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Generative-AI:.*:.*:read', 'jit:Generative-AI:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Conversions:cmd:.*:read'), (now(), now(), 'jit:GI-Conversions:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Conversions_cmd_JITVIEWER'), (now(), now(), 'GI-Conversions_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_cmd_JITVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:cmd:.*:read', 'jit:GI-Conversions:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Conversions:prod:.*:read'), (now(), now(), 'jit:GI-Conversions:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Conversions_prod_JITVIEWER'), (now(), now(), 'GI-Conversions_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_prod_JITVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_prod_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:prod:.*:read', 'jit:GI-Conversions:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Conversions:dev:.*:read'), (now(), now(), 'jit:GI-Conversions:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Conversions_dev_JITVIEWER'), (now(), now(), 'GI-Conversions_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_dev_JITVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_dev_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:dev:.*:read', 'jit:GI-Conversions:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Conversions:qa:.*:read'), (now(), now(), 'jit:GI-Conversions:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Conversions_qa_JITVIEWER'), (now(), now(), 'GI-Conversions_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_qa_JITVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_qa_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:qa:.*:read', 'jit:GI-Conversions:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Conversions:perf:.*:read'), (now(), now(), 'jit:GI-Conversions:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Conversions_perf_JITVIEWER'), (now(), now(), 'GI-Conversions_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_perf_JITVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_perf_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:perf:.*:read', 'jit:GI-Conversions:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Conversions:uat:.*:read'), (now(), now(), 'jit:GI-Conversions:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Conversions_uat_JITVIEWER'), (now(), now(), 'GI-Conversions_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_uat_JITVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_uat_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:uat:.*:read', 'jit:GI-Conversions:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Conversions:data-platform-prod:.*:read'), (now(), now(), 'jit:GI-Conversions:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Conversions_data-platform-prod_JITVIEWER'), (now(), now(), 'GI-Conversions_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:data-platform-prod:.*:read', 'jit:GI-Conversions:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Conversions:data-platform-nonprod:.*:read'), (now(), now(), 'jit:GI-Conversions:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Conversions_data-platform-nonprod_JITVIEWER'), (now(), now(), 'GI-Conversions_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:data-platform-nonprod:.*:read', 'jit:GI-Conversions:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Conversions:local:.*:read'), (now(), now(), 'jit:GI-Conversions:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Conversions_local_JITVIEWER'), (now(), now(), 'GI-Conversions_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_local_JITVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_local_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:local:.*:read', 'jit:GI-Conversions:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Conversions:.*:.*:read'), (now(), now(), 'jit:GI-Conversions:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Conversions_ALL_JITVIEWER'), (now(), now(), 'GI-Conversions_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_ALL_JITVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Conversions_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Conversions:.*:.*:read', 'jit:GI-Conversions:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Operations:cmd:.*:read'), (now(), now(), 'jit:GI-Operations:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Operations_cmd_JITVIEWER'), (now(), now(), 'GI-Operations_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_cmd_JITVIEWER' AND privilege.name IN ( 'jit:GI-Operations:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Operations:cmd:.*:read', 'jit:GI-Operations:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Operations:prod:.*:read'), (now(), now(), 'jit:GI-Operations:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Operations_prod_JITVIEWER'), (now(), now(), 'GI-Operations_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_prod_JITVIEWER' AND privilege.name IN ( 'jit:GI-Operations:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_prod_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Operations:prod:.*:read', 'jit:GI-Operations:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Operations:dev:.*:read'), (now(), now(), 'jit:GI-Operations:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Operations_dev_JITVIEWER'), (now(), now(), 'GI-Operations_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_dev_JITVIEWER' AND privilege.name IN ( 'jit:GI-Operations:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_dev_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Operations:dev:.*:read', 'jit:GI-Operations:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Operations:qa:.*:read'), (now(), now(), 'jit:GI-Operations:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Operations_qa_JITVIEWER'), (now(), now(), 'GI-Operations_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_qa_JITVIEWER' AND privilege.name IN ( 'jit:GI-Operations:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_qa_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Operations:qa:.*:read', 'jit:GI-Operations:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Operations:perf:.*:read'), (now(), now(), 'jit:GI-Operations:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Operations_perf_JITVIEWER'), (now(), now(), 'GI-Operations_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_perf_JITVIEWER' AND privilege.name IN ( 'jit:GI-Operations:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_perf_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Operations:perf:.*:read', 'jit:GI-Operations:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Operations:uat:.*:read'), (now(), now(), 'jit:GI-Operations:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Operations_uat_JITVIEWER'), (now(), now(), 'GI-Operations_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_uat_JITVIEWER' AND privilege.name IN ( 'jit:GI-Operations:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_uat_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Operations:uat:.*:read', 'jit:GI-Operations:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Operations:data-platform-prod:.*:read'), (now(), now(), 'jit:GI-Operations:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Operations_data-platform-prod_JITVIEWER'), (now(), now(), 'GI-Operations_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:GI-Operations:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Operations:data-platform-prod:.*:read', 'jit:GI-Operations:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Operations:data-platform-nonprod:.*:read'), (now(), now(), 'jit:GI-Operations:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Operations_data-platform-nonprod_JITVIEWER'), (now(), now(), 'GI-Operations_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:GI-Operations:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Operations:data-platform-nonprod:.*:read', 'jit:GI-Operations:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Operations:local:.*:read'), (now(), now(), 'jit:GI-Operations:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Operations_local_JITVIEWER'), (now(), now(), 'GI-Operations_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_local_JITVIEWER' AND privilege.name IN ( 'jit:GI-Operations:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_local_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Operations:local:.*:read', 'jit:GI-Operations:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GI-Operations:.*:.*:read'), (now(), now(), 'jit:GI-Operations:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GI-Operations_ALL_JITVIEWER'), (now(), now(), 'GI-Operations_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_ALL_JITVIEWER' AND privilege.name IN ( 'jit:GI-Operations:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GI-Operations_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:GI-Operations:.*:.*:read', 'jit:GI-Operations:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GrowthAndEngagement:cmd:.*:read'), (now(), now(), 'jit:GrowthAndEngagement:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GrowthAndEngagement_cmd_JITVIEWER'), (now(), now(), 'GrowthAndEngagement_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_cmd_JITVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:cmd:.*:read', 'jit:GrowthAndEngagement:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GrowthAndEngagement:prod:.*:read'), (now(), now(), 'jit:GrowthAndEngagement:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GrowthAndEngagement_prod_JITVIEWER'), (now(), now(), 'GrowthAndEngagement_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_prod_JITVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_prod_JITREVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:prod:.*:read', 'jit:GrowthAndEngagement:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GrowthAndEngagement:dev:.*:read'), (now(), now(), 'jit:GrowthAndEngagement:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GrowthAndEngagement_dev_JITVIEWER'), (now(), now(), 'GrowthAndEngagement_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_dev_JITVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_dev_JITREVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:dev:.*:read', 'jit:GrowthAndEngagement:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GrowthAndEngagement:qa:.*:read'), (now(), now(), 'jit:GrowthAndEngagement:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GrowthAndEngagement_qa_JITVIEWER'), (now(), now(), 'GrowthAndEngagement_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_qa_JITVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_qa_JITREVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:qa:.*:read', 'jit:GrowthAndEngagement:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GrowthAndEngagement:perf:.*:read'), (now(), now(), 'jit:GrowthAndEngagement:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GrowthAndEngagement_perf_JITVIEWER'), (now(), now(), 'GrowthAndEngagement_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_perf_JITVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_perf_JITREVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:perf:.*:read', 'jit:GrowthAndEngagement:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GrowthAndEngagement:uat:.*:read'), (now(), now(), 'jit:GrowthAndEngagement:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GrowthAndEngagement_uat_JITVIEWER'), (now(), now(), 'GrowthAndEngagement_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_uat_JITVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_uat_JITREVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:uat:.*:read', 'jit:GrowthAndEngagement:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GrowthAndEngagement:data-platform-prod:.*:read'), (now(), now(), 'jit:GrowthAndEngagement:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GrowthAndEngagement_data-platform-prod_JITVIEWER'), (now(), now(), 'GrowthAndEngagement_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:data-platform-prod:.*:read', 'jit:GrowthAndEngagement:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GrowthAndEngagement:data-platform-nonprod:.*:read'), (now(), now(), 'jit:GrowthAndEngagement:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GrowthAndEngagement_data-platform-nonprod_JITVIEWER'), (now(), now(), 'GrowthAndEngagement_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:data-platform-nonprod:.*:read', 'jit:GrowthAndEngagement:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GrowthAndEngagement:local:.*:read'), (now(), now(), 'jit:GrowthAndEngagement:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GrowthAndEngagement_local_JITVIEWER'), (now(), now(), 'GrowthAndEngagement_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_local_JITVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_local_JITREVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:local:.*:read', 'jit:GrowthAndEngagement:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:GrowthAndEngagement:.*:.*:read'), (now(), now(), 'jit:GrowthAndEngagement:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'GrowthAndEngagement_ALL_JITVIEWER'), (now(), now(), 'GrowthAndEngagement_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_ALL_JITVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'GrowthAndEngagement_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:GrowthAndEngagement:.*:.*:read', 'jit:GrowthAndEngagement:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Conversions:cmd:.*:read'), (now(), now(), 'jit:HL-Conversions:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Conversions_cmd_JITVIEWER'), (now(), now(), 'HL-Conversions_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_cmd_JITVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:cmd:.*:read', 'jit:HL-Conversions:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Conversions:prod:.*:read'), (now(), now(), 'jit:HL-Conversions:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Conversions_prod_JITVIEWER'), (now(), now(), 'HL-Conversions_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_prod_JITVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_prod_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:prod:.*:read', 'jit:HL-Conversions:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Conversions:dev:.*:read'), (now(), now(), 'jit:HL-Conversions:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Conversions_dev_JITVIEWER'), (now(), now(), 'HL-Conversions_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_dev_JITVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_dev_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:dev:.*:read', 'jit:HL-Conversions:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Conversions:qa:.*:read'), (now(), now(), 'jit:HL-Conversions:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Conversions_qa_JITVIEWER'), (now(), now(), 'HL-Conversions_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_qa_JITVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_qa_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:qa:.*:read', 'jit:HL-Conversions:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Conversions:perf:.*:read'), (now(), now(), 'jit:HL-Conversions:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Conversions_perf_JITVIEWER'), (now(), now(), 'HL-Conversions_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_perf_JITVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_perf_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:perf:.*:read', 'jit:HL-Conversions:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Conversions:uat:.*:read'), (now(), now(), 'jit:HL-Conversions:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Conversions_uat_JITVIEWER'), (now(), now(), 'HL-Conversions_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_uat_JITVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_uat_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:uat:.*:read', 'jit:HL-Conversions:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Conversions:data-platform-prod:.*:read'), (now(), now(), 'jit:HL-Conversions:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Conversions_data-platform-prod_JITVIEWER'), (now(), now(), 'HL-Conversions_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:data-platform-prod:.*:read', 'jit:HL-Conversions:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Conversions:data-platform-nonprod:.*:read'), (now(), now(), 'jit:HL-Conversions:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Conversions_data-platform-nonprod_JITVIEWER'), (now(), now(), 'HL-Conversions_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:data-platform-nonprod:.*:read', 'jit:HL-Conversions:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Conversions:local:.*:read'), (now(), now(), 'jit:HL-Conversions:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Conversions_local_JITVIEWER'), (now(), now(), 'HL-Conversions_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_local_JITVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_local_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:local:.*:read', 'jit:HL-Conversions:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Conversions:.*:.*:read'), (now(), now(), 'jit:HL-Conversions:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Conversions_ALL_JITVIEWER'), (now(), now(), 'HL-Conversions_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_ALL_JITVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Conversions_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Conversions:.*:.*:read', 'jit:HL-Conversions:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Operations:cmd:.*:read'), (now(), now(), 'jit:HL-Operations:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Operations_cmd_JITVIEWER'), (now(), now(), 'HL-Operations_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_cmd_JITVIEWER' AND privilege.name IN ( 'jit:HL-Operations:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Operations:cmd:.*:read', 'jit:HL-Operations:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Operations:prod:.*:read'), (now(), now(), 'jit:HL-Operations:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Operations_prod_JITVIEWER'), (now(), now(), 'HL-Operations_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_prod_JITVIEWER' AND privilege.name IN ( 'jit:HL-Operations:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_prod_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Operations:prod:.*:read', 'jit:HL-Operations:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Operations:dev:.*:read'), (now(), now(), 'jit:HL-Operations:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Operations_dev_JITVIEWER'), (now(), now(), 'HL-Operations_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_dev_JITVIEWER' AND privilege.name IN ( 'jit:HL-Operations:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_dev_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Operations:dev:.*:read', 'jit:HL-Operations:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Operations:qa:.*:read'), (now(), now(), 'jit:HL-Operations:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Operations_qa_JITVIEWER'), (now(), now(), 'HL-Operations_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_qa_JITVIEWER' AND privilege.name IN ( 'jit:HL-Operations:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_qa_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Operations:qa:.*:read', 'jit:HL-Operations:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Operations:perf:.*:read'), (now(), now(), 'jit:HL-Operations:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Operations_perf_JITVIEWER'), (now(), now(), 'HL-Operations_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_perf_JITVIEWER' AND privilege.name IN ( 'jit:HL-Operations:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_perf_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Operations:perf:.*:read', 'jit:HL-Operations:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Operations:uat:.*:read'), (now(), now(), 'jit:HL-Operations:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Operations_uat_JITVIEWER'), (now(), now(), 'HL-Operations_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_uat_JITVIEWER' AND privilege.name IN ( 'jit:HL-Operations:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_uat_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Operations:uat:.*:read', 'jit:HL-Operations:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Operations:data-platform-prod:.*:read'), (now(), now(), 'jit:HL-Operations:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Operations_data-platform-prod_JITVIEWER'), (now(), now(), 'HL-Operations_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:HL-Operations:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Operations:data-platform-prod:.*:read', 'jit:HL-Operations:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Operations:data-platform-nonprod:.*:read'), (now(), now(), 'jit:HL-Operations:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Operations_data-platform-nonprod_JITVIEWER'), (now(), now(), 'HL-Operations_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:HL-Operations:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Operations:data-platform-nonprod:.*:read', 'jit:HL-Operations:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Operations:local:.*:read'), (now(), now(), 'jit:HL-Operations:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Operations_local_JITVIEWER'), (now(), now(), 'HL-Operations_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_local_JITVIEWER' AND privilege.name IN ( 'jit:HL-Operations:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_local_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Operations:local:.*:read', 'jit:HL-Operations:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:HL-Operations:.*:.*:read'), (now(), now(), 'jit:HL-Operations:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'HL-Operations_ALL_JITVIEWER'), (now(), now(), 'HL-Operations_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_ALL_JITVIEWER' AND privilege.name IN ( 'jit:HL-Operations:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'HL-Operations_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:HL-Operations:.*:.*:read', 'jit:HL-Operations:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Infra:cmd:.*:read'), (now(), now(), 'jit:Infra:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Infra_cmd_JITVIEWER'), (now(), now(), 'Infra_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Infra:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Infra:cmd:.*:read', 'jit:Infra:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Infra:prod:.*:read'), (now(), now(), 'jit:Infra:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Infra_prod_JITVIEWER'), (now(), now(), 'Infra_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_prod_JITVIEWER' AND privilege.name IN ( 'jit:Infra:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Infra:prod:.*:read', 'jit:Infra:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Infra:dev:.*:read'), (now(), now(), 'jit:Infra:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Infra_dev_JITVIEWER'), (now(), now(), 'Infra_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_dev_JITVIEWER' AND privilege.name IN ( 'jit:Infra:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Infra:dev:.*:read', 'jit:Infra:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Infra:qa:.*:read'), (now(), now(), 'jit:Infra:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Infra_qa_JITVIEWER'), (now(), now(), 'Infra_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_qa_JITVIEWER' AND privilege.name IN ( 'jit:Infra:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Infra:qa:.*:read', 'jit:Infra:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Infra:perf:.*:read'), (now(), now(), 'jit:Infra:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Infra_perf_JITVIEWER'), (now(), now(), 'Infra_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_perf_JITVIEWER' AND privilege.name IN ( 'jit:Infra:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Infra:perf:.*:read', 'jit:Infra:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Infra:uat:.*:read'), (now(), now(), 'jit:Infra:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Infra_uat_JITVIEWER'), (now(), now(), 'Infra_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_uat_JITVIEWER' AND privilege.name IN ( 'jit:Infra:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Infra:uat:.*:read', 'jit:Infra:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Infra:data-platform-prod:.*:read'), (now(), now(), 'jit:Infra:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Infra_data-platform-prod_JITVIEWER'), (now(), now(), 'Infra_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Infra:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Infra:data-platform-prod:.*:read', 'jit:Infra:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Infra:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Infra:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Infra_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Infra_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Infra:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Infra:data-platform-nonprod:.*:read', 'jit:Infra:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Infra:local:.*:read'), (now(), now(), 'jit:Infra:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Infra_local_JITVIEWER'), (now(), now(), 'Infra_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_local_JITVIEWER' AND privilege.name IN ( 'jit:Infra:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_local_JITREVIEWER' AND privilege.name IN ( 'jit:Infra:local:.*:read', 'jit:Infra:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Infra:.*:.*:read'), (now(), now(), 'jit:Infra:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Infra_ALL_JITVIEWER'), (now(), now(), 'Infra_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Infra:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Infra_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Infra:.*:.*:read', 'jit:Infra:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:insurance-operations:cmd:.*:read'), (now(), now(), 'jit:insurance-operations:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'insurance-operations_cmd_JITVIEWER'), (now(), now(), 'insurance-operations_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_cmd_JITVIEWER' AND privilege.name IN ( 'jit:insurance-operations:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:insurance-operations:cmd:.*:read', 'jit:insurance-operations:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:insurance-operations:prod:.*:read'), (now(), now(), 'jit:insurance-operations:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'insurance-operations_prod_JITVIEWER'), (now(), now(), 'insurance-operations_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_prod_JITVIEWER' AND privilege.name IN ( 'jit:insurance-operations:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_prod_JITREVIEWER' AND privilege.name IN ( 'jit:insurance-operations:prod:.*:read', 'jit:insurance-operations:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:insurance-operations:dev:.*:read'), (now(), now(), 'jit:insurance-operations:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'insurance-operations_dev_JITVIEWER'), (now(), now(), 'insurance-operations_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_dev_JITVIEWER' AND privilege.name IN ( 'jit:insurance-operations:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_dev_JITREVIEWER' AND privilege.name IN ( 'jit:insurance-operations:dev:.*:read', 'jit:insurance-operations:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:insurance-operations:qa:.*:read'), (now(), now(), 'jit:insurance-operations:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'insurance-operations_qa_JITVIEWER'), (now(), now(), 'insurance-operations_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_qa_JITVIEWER' AND privilege.name IN ( 'jit:insurance-operations:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_qa_JITREVIEWER' AND privilege.name IN ( 'jit:insurance-operations:qa:.*:read', 'jit:insurance-operations:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:insurance-operations:perf:.*:read'), (now(), now(), 'jit:insurance-operations:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'insurance-operations_perf_JITVIEWER'), (now(), now(), 'insurance-operations_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_perf_JITVIEWER' AND privilege.name IN ( 'jit:insurance-operations:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_perf_JITREVIEWER' AND privilege.name IN ( 'jit:insurance-operations:perf:.*:read', 'jit:insurance-operations:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:insurance-operations:uat:.*:read'), (now(), now(), 'jit:insurance-operations:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'insurance-operations_uat_JITVIEWER'), (now(), now(), 'insurance-operations_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_uat_JITVIEWER' AND privilege.name IN ( 'jit:insurance-operations:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_uat_JITREVIEWER' AND privilege.name IN ( 'jit:insurance-operations:uat:.*:read', 'jit:insurance-operations:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:insurance-operations:data-platform-prod:.*:read'), (now(), now(), 'jit:insurance-operations:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'insurance-operations_data-platform-prod_JITVIEWER'), (now(), now(), 'insurance-operations_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:insurance-operations:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:insurance-operations:data-platform-prod:.*:read', 'jit:insurance-operations:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:insurance-operations:data-platform-nonprod:.*:read'), (now(), now(), 'jit:insurance-operations:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'insurance-operations_data-platform-nonprod_JITVIEWER'), (now(), now(), 'insurance-operations_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:insurance-operations:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:insurance-operations:data-platform-nonprod:.*:read', 'jit:insurance-operations:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:insurance-operations:local:.*:read'), (now(), now(), 'jit:insurance-operations:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'insurance-operations_local_JITVIEWER'), (now(), now(), 'insurance-operations_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_local_JITVIEWER' AND privilege.name IN ( 'jit:insurance-operations:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_local_JITREVIEWER' AND privilege.name IN ( 'jit:insurance-operations:local:.*:read', 'jit:insurance-operations:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:insurance-operations:.*:.*:read'), (now(), now(), 'jit:insurance-operations:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'insurance-operations_ALL_JITVIEWER'), (now(), now(), 'insurance-operations_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_ALL_JITVIEWER' AND privilege.name IN ( 'jit:insurance-operations:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'insurance-operations_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:insurance-operations:.*:.*:read', 'jit:insurance-operations:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:InsurancePlatform:cmd:.*:read'), (now(), now(), 'jit:InsurancePlatform:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'InsurancePlatform_cmd_JITVIEWER'), (now(), now(), 'InsurancePlatform_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_cmd_JITVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:cmd:.*:read', 'jit:InsurancePlatform:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:InsurancePlatform:prod:.*:read'), (now(), now(), 'jit:InsurancePlatform:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'InsurancePlatform_prod_JITVIEWER'), (now(), now(), 'InsurancePlatform_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_prod_JITVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_prod_JITREVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:prod:.*:read', 'jit:InsurancePlatform:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:InsurancePlatform:dev:.*:read'), (now(), now(), 'jit:InsurancePlatform:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'InsurancePlatform_dev_JITVIEWER'), (now(), now(), 'InsurancePlatform_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_dev_JITVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_dev_JITREVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:dev:.*:read', 'jit:InsurancePlatform:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:InsurancePlatform:qa:.*:read'), (now(), now(), 'jit:InsurancePlatform:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'InsurancePlatform_qa_JITVIEWER'), (now(), now(), 'InsurancePlatform_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_qa_JITVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_qa_JITREVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:qa:.*:read', 'jit:InsurancePlatform:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:InsurancePlatform:perf:.*:read'), (now(), now(), 'jit:InsurancePlatform:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'InsurancePlatform_perf_JITVIEWER'), (now(), now(), 'InsurancePlatform_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_perf_JITVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_perf_JITREVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:perf:.*:read', 'jit:InsurancePlatform:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:InsurancePlatform:uat:.*:read'), (now(), now(), 'jit:InsurancePlatform:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'InsurancePlatform_uat_JITVIEWER'), (now(), now(), 'InsurancePlatform_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_uat_JITVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_uat_JITREVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:uat:.*:read', 'jit:InsurancePlatform:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:InsurancePlatform:data-platform-prod:.*:read'), (now(), now(), 'jit:InsurancePlatform:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'InsurancePlatform_data-platform-prod_JITVIEWER'), (now(), now(), 'InsurancePlatform_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:data-platform-prod:.*:read', 'jit:InsurancePlatform:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:InsurancePlatform:data-platform-nonprod:.*:read'), (now(), now(), 'jit:InsurancePlatform:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'InsurancePlatform_data-platform-nonprod_JITVIEWER'), (now(), now(), 'InsurancePlatform_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:data-platform-nonprod:.*:read', 'jit:InsurancePlatform:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:InsurancePlatform:local:.*:read'), (now(), now(), 'jit:InsurancePlatform:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'InsurancePlatform_local_JITVIEWER'), (now(), now(), 'InsurancePlatform_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_local_JITVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_local_JITREVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:local:.*:read', 'jit:InsurancePlatform:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:InsurancePlatform:.*:.*:read'), (now(), now(), 'jit:InsurancePlatform:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'InsurancePlatform_ALL_JITVIEWER'), (now(), now(), 'InsurancePlatform_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_ALL_JITVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'InsurancePlatform_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:InsurancePlatform:.*:.*:read', 'jit:InsurancePlatform:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:KYC:cmd:.*:read'), (now(), now(), 'jit:KYC:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'KYC_cmd_JITVIEWER'), (now(), now(), 'KYC_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_cmd_JITVIEWER' AND privilege.name IN ( 'jit:KYC:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:KYC:cmd:.*:read', 'jit:KYC:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:KYC:prod:.*:read'), (now(), now(), 'jit:KYC:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'KYC_prod_JITVIEWER'), (now(), now(), 'KYC_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_prod_JITVIEWER' AND privilege.name IN ( 'jit:KYC:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_prod_JITREVIEWER' AND privilege.name IN ( 'jit:KYC:prod:.*:read', 'jit:KYC:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:KYC:dev:.*:read'), (now(), now(), 'jit:KYC:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'KYC_dev_JITVIEWER'), (now(), now(), 'KYC_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_dev_JITVIEWER' AND privilege.name IN ( 'jit:KYC:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_dev_JITREVIEWER' AND privilege.name IN ( 'jit:KYC:dev:.*:read', 'jit:KYC:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:KYC:qa:.*:read'), (now(), now(), 'jit:KYC:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'KYC_qa_JITVIEWER'), (now(), now(), 'KYC_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_qa_JITVIEWER' AND privilege.name IN ( 'jit:KYC:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_qa_JITREVIEWER' AND privilege.name IN ( 'jit:KYC:qa:.*:read', 'jit:KYC:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:KYC:perf:.*:read'), (now(), now(), 'jit:KYC:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'KYC_perf_JITVIEWER'), (now(), now(), 'KYC_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_perf_JITVIEWER' AND privilege.name IN ( 'jit:KYC:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_perf_JITREVIEWER' AND privilege.name IN ( 'jit:KYC:perf:.*:read', 'jit:KYC:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:KYC:uat:.*:read'), (now(), now(), 'jit:KYC:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'KYC_uat_JITVIEWER'), (now(), now(), 'KYC_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_uat_JITVIEWER' AND privilege.name IN ( 'jit:KYC:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_uat_JITREVIEWER' AND privilege.name IN ( 'jit:KYC:uat:.*:read', 'jit:KYC:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:KYC:data-platform-prod:.*:read'), (now(), now(), 'jit:KYC:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'KYC_data-platform-prod_JITVIEWER'), (now(), now(), 'KYC_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:KYC:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:KYC:data-platform-prod:.*:read', 'jit:KYC:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:KYC:data-platform-nonprod:.*:read'), (now(), now(), 'jit:KYC:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'KYC_data-platform-nonprod_JITVIEWER'), (now(), now(), 'KYC_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:KYC:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:KYC:data-platform-nonprod:.*:read', 'jit:KYC:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:KYC:local:.*:read'), (now(), now(), 'jit:KYC:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'KYC_local_JITVIEWER'), (now(), now(), 'KYC_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_local_JITVIEWER' AND privilege.name IN ( 'jit:KYC:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_local_JITREVIEWER' AND privilege.name IN ( 'jit:KYC:local:.*:read', 'jit:KYC:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:KYC:.*:.*:read'), (now(), now(), 'jit:KYC:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'KYC_ALL_JITVIEWER'), (now(), now(), 'KYC_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_ALL_JITVIEWER' AND privilege.name IN ( 'jit:KYC:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'KYC_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:KYC:.*:.*:read', 'jit:KYC:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:lending-operations:cmd:.*:read'), (now(), now(), 'jit:lending-operations:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'lending-operations_cmd_JITVIEWER'), (now(), now(), 'lending-operations_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_cmd_JITVIEWER' AND privilege.name IN ( 'jit:lending-operations:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:lending-operations:cmd:.*:read', 'jit:lending-operations:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:lending-operations:prod:.*:read'), (now(), now(), 'jit:lending-operations:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'lending-operations_prod_JITVIEWER'), (now(), now(), 'lending-operations_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_prod_JITVIEWER' AND privilege.name IN ( 'jit:lending-operations:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_prod_JITREVIEWER' AND privilege.name IN ( 'jit:lending-operations:prod:.*:read', 'jit:lending-operations:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:lending-operations:dev:.*:read'), (now(), now(), 'jit:lending-operations:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'lending-operations_dev_JITVIEWER'), (now(), now(), 'lending-operations_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_dev_JITVIEWER' AND privilege.name IN ( 'jit:lending-operations:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_dev_JITREVIEWER' AND privilege.name IN ( 'jit:lending-operations:dev:.*:read', 'jit:lending-operations:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:lending-operations:qa:.*:read'), (now(), now(), 'jit:lending-operations:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'lending-operations_qa_JITVIEWER'), (now(), now(), 'lending-operations_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_qa_JITVIEWER' AND privilege.name IN ( 'jit:lending-operations:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_qa_JITREVIEWER' AND privilege.name IN ( 'jit:lending-operations:qa:.*:read', 'jit:lending-operations:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:lending-operations:perf:.*:read'), (now(), now(), 'jit:lending-operations:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'lending-operations_perf_JITVIEWER'), (now(), now(), 'lending-operations_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_perf_JITVIEWER' AND privilege.name IN ( 'jit:lending-operations:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_perf_JITREVIEWER' AND privilege.name IN ( 'jit:lending-operations:perf:.*:read', 'jit:lending-operations:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:lending-operations:uat:.*:read'), (now(), now(), 'jit:lending-operations:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'lending-operations_uat_JITVIEWER'), (now(), now(), 'lending-operations_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_uat_JITVIEWER' AND privilege.name IN ( 'jit:lending-operations:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_uat_JITREVIEWER' AND privilege.name IN ( 'jit:lending-operations:uat:.*:read', 'jit:lending-operations:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:lending-operations:data-platform-prod:.*:read'), (now(), now(), 'jit:lending-operations:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'lending-operations_data-platform-prod_JITVIEWER'), (now(), now(), 'lending-operations_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:lending-operations:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:lending-operations:data-platform-prod:.*:read', 'jit:lending-operations:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:lending-operations:data-platform-nonprod:.*:read'), (now(), now(), 'jit:lending-operations:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'lending-operations_data-platform-nonprod_JITVIEWER'), (now(), now(), 'lending-operations_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:lending-operations:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:lending-operations:data-platform-nonprod:.*:read', 'jit:lending-operations:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:lending-operations:local:.*:read'), (now(), now(), 'jit:lending-operations:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'lending-operations_local_JITVIEWER'), (now(), now(), 'lending-operations_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_local_JITVIEWER' AND privilege.name IN ( 'jit:lending-operations:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_local_JITREVIEWER' AND privilege.name IN ( 'jit:lending-operations:local:.*:read', 'jit:lending-operations:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:lending-operations:.*:.*:read'), (now(), now(), 'jit:lending-operations:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'lending-operations_ALL_JITVIEWER'), (now(), now(), 'lending-operations_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_ALL_JITVIEWER' AND privilege.name IN ( 'jit:lending-operations:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'lending-operations_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:lending-operations:.*:.*:read', 'jit:lending-operations:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:LMSAndAccounting:cmd:.*:read'), (now(), now(), 'jit:LMSAndAccounting:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'LMSAndAccounting_cmd_JITVIEWER'), (now(), now(), 'LMSAndAccounting_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_cmd_JITVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:cmd:.*:read', 'jit:LMSAndAccounting:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:LMSAndAccounting:prod:.*:read'), (now(), now(), 'jit:LMSAndAccounting:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'LMSAndAccounting_prod_JITVIEWER'), (now(), now(), 'LMSAndAccounting_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_prod_JITVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_prod_JITREVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:prod:.*:read', 'jit:LMSAndAccounting:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:LMSAndAccounting:dev:.*:read'), (now(), now(), 'jit:LMSAndAccounting:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'LMSAndAccounting_dev_JITVIEWER'), (now(), now(), 'LMSAndAccounting_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_dev_JITVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_dev_JITREVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:dev:.*:read', 'jit:LMSAndAccounting:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:LMSAndAccounting:qa:.*:read'), (now(), now(), 'jit:LMSAndAccounting:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'LMSAndAccounting_qa_JITVIEWER'), (now(), now(), 'LMSAndAccounting_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_qa_JITVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_qa_JITREVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:qa:.*:read', 'jit:LMSAndAccounting:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:LMSAndAccounting:perf:.*:read'), (now(), now(), 'jit:LMSAndAccounting:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'LMSAndAccounting_perf_JITVIEWER'), (now(), now(), 'LMSAndAccounting_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_perf_JITVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_perf_JITREVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:perf:.*:read', 'jit:LMSAndAccounting:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:LMSAndAccounting:uat:.*:read'), (now(), now(), 'jit:LMSAndAccounting:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'LMSAndAccounting_uat_JITVIEWER'), (now(), now(), 'LMSAndAccounting_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_uat_JITVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_uat_JITREVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:uat:.*:read', 'jit:LMSAndAccounting:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:LMSAndAccounting:data-platform-prod:.*:read'), (now(), now(), 'jit:LMSAndAccounting:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'LMSAndAccounting_data-platform-prod_JITVIEWER'), (now(), now(), 'LMSAndAccounting_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:data-platform-prod:.*:read', 'jit:LMSAndAccounting:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:LMSAndAccounting:data-platform-nonprod:.*:read'), (now(), now(), 'jit:LMSAndAccounting:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'LMSAndAccounting_data-platform-nonprod_JITVIEWER'), (now(), now(), 'LMSAndAccounting_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:data-platform-nonprod:.*:read', 'jit:LMSAndAccounting:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:LMSAndAccounting:local:.*:read'), (now(), now(), 'jit:LMSAndAccounting:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'LMSAndAccounting_local_JITVIEWER'), (now(), now(), 'LMSAndAccounting_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_local_JITVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_local_JITREVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:local:.*:read', 'jit:LMSAndAccounting:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:LMSAndAccounting:.*:.*:read'), (now(), now(), 'jit:LMSAndAccounting:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'LMSAndAccounting_ALL_JITVIEWER'), (now(), now(), 'LMSAndAccounting_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_ALL_JITVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'LMSAndAccounting_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:LMSAndAccounting:.*:.*:read', 'jit:LMSAndAccounting:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Pay:cmd:.*:read'), (now(), now(), 'jit:Navi-Pay:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Pay_cmd_JITVIEWER'), (now(), now(), 'Navi-Pay_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:cmd:.*:read', 'jit:Navi-Pay:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Pay:prod:.*:read'), (now(), now(), 'jit:Navi-Pay:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Pay_prod_JITVIEWER'), (now(), now(), 'Navi-Pay_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_prod_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:prod:.*:read', 'jit:Navi-Pay:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Pay:dev:.*:read'), (now(), now(), 'jit:Navi-Pay:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Pay_dev_JITVIEWER'), (now(), now(), 'Navi-Pay_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_dev_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:dev:.*:read', 'jit:Navi-Pay:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Pay:qa:.*:read'), (now(), now(), 'jit:Navi-Pay:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Pay_qa_JITVIEWER'), (now(), now(), 'Navi-Pay_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_qa_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:qa:.*:read', 'jit:Navi-Pay:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Pay:perf:.*:read'), (now(), now(), 'jit:Navi-Pay:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Pay_perf_JITVIEWER'), (now(), now(), 'Navi-Pay_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_perf_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:perf:.*:read', 'jit:Navi-Pay:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Pay:uat:.*:read'), (now(), now(), 'jit:Navi-Pay:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Pay_uat_JITVIEWER'), (now(), now(), 'Navi-Pay_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_uat_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:uat:.*:read', 'jit:Navi-Pay:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Pay:data-platform-prod:.*:read'), (now(), now(), 'jit:Navi-Pay:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Pay_data-platform-prod_JITVIEWER'), (now(), now(), 'Navi-Pay_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:data-platform-prod:.*:read', 'jit:Navi-Pay:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Pay:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Navi-Pay:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Pay_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Navi-Pay_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:data-platform-nonprod:.*:read', 'jit:Navi-Pay:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Pay:local:.*:read'), (now(), now(), 'jit:Navi-Pay:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Pay_local_JITVIEWER'), (now(), now(), 'Navi-Pay_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_local_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_local_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:local:.*:read', 'jit:Navi-Pay:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Pay:.*:.*:read'), (now(), now(), 'jit:Navi-Pay:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Pay_ALL_JITVIEWER'), (now(), now(), 'Navi-Pay_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Pay_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Pay:.*:.*:read', 'jit:Navi-Pay:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Saas:cmd:.*:read'), (now(), now(), 'jit:Navi-Saas:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Saas_cmd_JITVIEWER'), (now(), now(), 'Navi-Saas_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:cmd:.*:read', 'jit:Navi-Saas:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Saas:prod:.*:read'), (now(), now(), 'jit:Navi-Saas:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Saas_prod_JITVIEWER'), (now(), now(), 'Navi-Saas_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_prod_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:prod:.*:read', 'jit:Navi-Saas:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Saas:dev:.*:read'), (now(), now(), 'jit:Navi-Saas:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Saas_dev_JITVIEWER'), (now(), now(), 'Navi-Saas_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_dev_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:dev:.*:read', 'jit:Navi-Saas:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Saas:qa:.*:read'), (now(), now(), 'jit:Navi-Saas:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Saas_qa_JITVIEWER'), (now(), now(), 'Navi-Saas_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_qa_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:qa:.*:read', 'jit:Navi-Saas:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Saas:perf:.*:read'), (now(), now(), 'jit:Navi-Saas:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Saas_perf_JITVIEWER'), (now(), now(), 'Navi-Saas_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_perf_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:perf:.*:read', 'jit:Navi-Saas:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Saas:uat:.*:read'), (now(), now(), 'jit:Navi-Saas:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Saas_uat_JITVIEWER'), (now(), now(), 'Navi-Saas_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_uat_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:uat:.*:read', 'jit:Navi-Saas:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Saas:data-platform-prod:.*:read'), (now(), now(), 'jit:Navi-Saas:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Saas_data-platform-prod_JITVIEWER'), (now(), now(), 'Navi-Saas_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:data-platform-prod:.*:read', 'jit:Navi-Saas:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Saas:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Navi-Saas:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Saas_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Navi-Saas_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:data-platform-nonprod:.*:read', 'jit:Navi-Saas:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Saas:local:.*:read'), (now(), now(), 'jit:Navi-Saas:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Saas_local_JITVIEWER'), (now(), now(), 'Navi-Saas_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_local_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_local_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:local:.*:read', 'jit:Navi-Saas:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Saas:.*:.*:read'), (now(), now(), 'jit:Navi-Saas:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Saas_ALL_JITVIEWER'), (now(), now(), 'Navi-Saas_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Saas_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Saas:.*:.*:read', 'jit:Navi-Saas:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Website:cmd:.*:read'), (now(), now(), 'jit:Navi-Website:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Website_cmd_JITVIEWER'), (now(), now(), 'Navi-Website_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Website:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Website:cmd:.*:read', 'jit:Navi-Website:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Website:prod:.*:read'), (now(), now(), 'jit:Navi-Website:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Website_prod_JITVIEWER'), (now(), now(), 'Navi-Website_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_prod_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Website:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Website:prod:.*:read', 'jit:Navi-Website:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Website:dev:.*:read'), (now(), now(), 'jit:Navi-Website:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Website_dev_JITVIEWER'), (now(), now(), 'Navi-Website_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_dev_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Website:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Website:dev:.*:read', 'jit:Navi-Website:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Website:qa:.*:read'), (now(), now(), 'jit:Navi-Website:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Website_qa_JITVIEWER'), (now(), now(), 'Navi-Website_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_qa_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Website:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Website:qa:.*:read', 'jit:Navi-Website:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Website:perf:.*:read'), (now(), now(), 'jit:Navi-Website:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Website_perf_JITVIEWER'), (now(), now(), 'Navi-Website_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_perf_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Website:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Website:perf:.*:read', 'jit:Navi-Website:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Website:uat:.*:read'), (now(), now(), 'jit:Navi-Website:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Website_uat_JITVIEWER'), (now(), now(), 'Navi-Website_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_uat_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Website:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Website:uat:.*:read', 'jit:Navi-Website:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Website:data-platform-prod:.*:read'), (now(), now(), 'jit:Navi-Website:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Website_data-platform-prod_JITVIEWER'), (now(), now(), 'Navi-Website_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Website:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Website:data-platform-prod:.*:read', 'jit:Navi-Website:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Website:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Navi-Website:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Website_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Navi-Website_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Website:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Website:data-platform-nonprod:.*:read', 'jit:Navi-Website:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Website:local:.*:read'), (now(), now(), 'jit:Navi-Website:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Website_local_JITVIEWER'), (now(), now(), 'Navi-Website_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_local_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Website:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_local_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Website:local:.*:read', 'jit:Navi-Website:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Navi-Website:.*:.*:read'), (now(), now(), 'jit:Navi-Website:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Navi-Website_ALL_JITVIEWER'), (now(), now(), 'Navi-Website_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Navi-Website:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Navi-Website_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Navi-Website:.*:.*:read', 'jit:Navi-Website:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PAXCore:cmd:.*:read'), (now(), now(), 'jit:PAXCore:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PAXCore_cmd_JITVIEWER'), (now(), now(), 'PAXCore_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_cmd_JITVIEWER' AND privilege.name IN ( 'jit:PAXCore:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:PAXCore:cmd:.*:read', 'jit:PAXCore:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PAXCore:prod:.*:read'), (now(), now(), 'jit:PAXCore:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PAXCore_prod_JITVIEWER'), (now(), now(), 'PAXCore_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_prod_JITVIEWER' AND privilege.name IN ( 'jit:PAXCore:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_prod_JITREVIEWER' AND privilege.name IN ( 'jit:PAXCore:prod:.*:read', 'jit:PAXCore:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PAXCore:dev:.*:read'), (now(), now(), 'jit:PAXCore:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PAXCore_dev_JITVIEWER'), (now(), now(), 'PAXCore_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_dev_JITVIEWER' AND privilege.name IN ( 'jit:PAXCore:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_dev_JITREVIEWER' AND privilege.name IN ( 'jit:PAXCore:dev:.*:read', 'jit:PAXCore:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PAXCore:qa:.*:read'), (now(), now(), 'jit:PAXCore:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PAXCore_qa_JITVIEWER'), (now(), now(), 'PAXCore_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_qa_JITVIEWER' AND privilege.name IN ( 'jit:PAXCore:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_qa_JITREVIEWER' AND privilege.name IN ( 'jit:PAXCore:qa:.*:read', 'jit:PAXCore:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PAXCore:perf:.*:read'), (now(), now(), 'jit:PAXCore:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PAXCore_perf_JITVIEWER'), (now(), now(), 'PAXCore_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_perf_JITVIEWER' AND privilege.name IN ( 'jit:PAXCore:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_perf_JITREVIEWER' AND privilege.name IN ( 'jit:PAXCore:perf:.*:read', 'jit:PAXCore:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PAXCore:uat:.*:read'), (now(), now(), 'jit:PAXCore:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PAXCore_uat_JITVIEWER'), (now(), now(), 'PAXCore_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_uat_JITVIEWER' AND privilege.name IN ( 'jit:PAXCore:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_uat_JITREVIEWER' AND privilege.name IN ( 'jit:PAXCore:uat:.*:read', 'jit:PAXCore:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PAXCore:data-platform-prod:.*:read'), (now(), now(), 'jit:PAXCore:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PAXCore_data-platform-prod_JITVIEWER'), (now(), now(), 'PAXCore_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:PAXCore:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:PAXCore:data-platform-prod:.*:read', 'jit:PAXCore:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PAXCore:data-platform-nonprod:.*:read'), (now(), now(), 'jit:PAXCore:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PAXCore_data-platform-nonprod_JITVIEWER'), (now(), now(), 'PAXCore_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:PAXCore:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:PAXCore:data-platform-nonprod:.*:read', 'jit:PAXCore:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PAXCore:local:.*:read'), (now(), now(), 'jit:PAXCore:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PAXCore_local_JITVIEWER'), (now(), now(), 'PAXCore_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_local_JITVIEWER' AND privilege.name IN ( 'jit:PAXCore:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_local_JITREVIEWER' AND privilege.name IN ( 'jit:PAXCore:local:.*:read', 'jit:PAXCore:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PAXCore:.*:.*:read'), (now(), now(), 'jit:PAXCore:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PAXCore_ALL_JITVIEWER'), (now(), now(), 'PAXCore_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_ALL_JITVIEWER' AND privilege.name IN ( 'jit:PAXCore:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PAXCore_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:PAXCore:.*:.*:read', 'jit:PAXCore:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Payments:cmd:.*:read'), (now(), now(), 'jit:Payments:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Payments_cmd_JITVIEWER'), (now(), now(), 'Payments_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Payments:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Payments:cmd:.*:read', 'jit:Payments:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Payments:prod:.*:read'), (now(), now(), 'jit:Payments:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Payments_prod_JITVIEWER'), (now(), now(), 'Payments_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_prod_JITVIEWER' AND privilege.name IN ( 'jit:Payments:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Payments:prod:.*:read', 'jit:Payments:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Payments:dev:.*:read'), (now(), now(), 'jit:Payments:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Payments_dev_JITVIEWER'), (now(), now(), 'Payments_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_dev_JITVIEWER' AND privilege.name IN ( 'jit:Payments:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Payments:dev:.*:read', 'jit:Payments:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Payments:qa:.*:read'), (now(), now(), 'jit:Payments:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Payments_qa_JITVIEWER'), (now(), now(), 'Payments_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_qa_JITVIEWER' AND privilege.name IN ( 'jit:Payments:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Payments:qa:.*:read', 'jit:Payments:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Payments:perf:.*:read'), (now(), now(), 'jit:Payments:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Payments_perf_JITVIEWER'), (now(), now(), 'Payments_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_perf_JITVIEWER' AND privilege.name IN ( 'jit:Payments:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Payments:perf:.*:read', 'jit:Payments:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Payments:uat:.*:read'), (now(), now(), 'jit:Payments:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Payments_uat_JITVIEWER'), (now(), now(), 'Payments_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_uat_JITVIEWER' AND privilege.name IN ( 'jit:Payments:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Payments:uat:.*:read', 'jit:Payments:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Payments:data-platform-prod:.*:read'), (now(), now(), 'jit:Payments:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Payments_data-platform-prod_JITVIEWER'), (now(), now(), 'Payments_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Payments:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Payments:data-platform-prod:.*:read', 'jit:Payments:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Payments:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Payments:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Payments_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Payments_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Payments:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Payments:data-platform-nonprod:.*:read', 'jit:Payments:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Payments:local:.*:read'), (now(), now(), 'jit:Payments:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Payments_local_JITVIEWER'), (now(), now(), 'Payments_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_local_JITVIEWER' AND privilege.name IN ( 'jit:Payments:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_local_JITREVIEWER' AND privilege.name IN ( 'jit:Payments:local:.*:read', 'jit:Payments:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Payments:.*:.*:read'), (now(), now(), 'jit:Payments:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Payments_ALL_JITVIEWER'), (now(), now(), 'Payments_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Payments:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Payments_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Payments:.*:.*:read', 'jit:Payments:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Conversions:cmd:.*:read'), (now(), now(), 'jit:PL-Conversions:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Conversions_cmd_JITVIEWER'), (now(), now(), 'PL-Conversions_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_cmd_JITVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:cmd:.*:read', 'jit:PL-Conversions:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Conversions:prod:.*:read'), (now(), now(), 'jit:PL-Conversions:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Conversions_prod_JITVIEWER'), (now(), now(), 'PL-Conversions_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_prod_JITVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_prod_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:prod:.*:read', 'jit:PL-Conversions:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Conversions:dev:.*:read'), (now(), now(), 'jit:PL-Conversions:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Conversions_dev_JITVIEWER'), (now(), now(), 'PL-Conversions_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_dev_JITVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_dev_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:dev:.*:read', 'jit:PL-Conversions:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Conversions:qa:.*:read'), (now(), now(), 'jit:PL-Conversions:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Conversions_qa_JITVIEWER'), (now(), now(), 'PL-Conversions_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_qa_JITVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_qa_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:qa:.*:read', 'jit:PL-Conversions:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Conversions:perf:.*:read'), (now(), now(), 'jit:PL-Conversions:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Conversions_perf_JITVIEWER'), (now(), now(), 'PL-Conversions_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_perf_JITVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_perf_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:perf:.*:read', 'jit:PL-Conversions:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Conversions:uat:.*:read'), (now(), now(), 'jit:PL-Conversions:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Conversions_uat_JITVIEWER'), (now(), now(), 'PL-Conversions_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_uat_JITVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_uat_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:uat:.*:read', 'jit:PL-Conversions:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Conversions:data-platform-prod:.*:read'), (now(), now(), 'jit:PL-Conversions:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Conversions_data-platform-prod_JITVIEWER'), (now(), now(), 'PL-Conversions_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:data-platform-prod:.*:read', 'jit:PL-Conversions:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Conversions:data-platform-nonprod:.*:read'), (now(), now(), 'jit:PL-Conversions:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Conversions_data-platform-nonprod_JITVIEWER'), (now(), now(), 'PL-Conversions_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:data-platform-nonprod:.*:read', 'jit:PL-Conversions:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Conversions:local:.*:read'), (now(), now(), 'jit:PL-Conversions:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Conversions_local_JITVIEWER'), (now(), now(), 'PL-Conversions_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_local_JITVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_local_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:local:.*:read', 'jit:PL-Conversions:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Conversions:.*:.*:read'), (now(), now(), 'jit:PL-Conversions:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Conversions_ALL_JITVIEWER'), (now(), now(), 'PL-Conversions_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_ALL_JITVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Conversions_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Conversions:.*:.*:read', 'jit:PL-Conversions:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Operations:cmd:.*:read'), (now(), now(), 'jit:PL-Operations:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Operations_cmd_JITVIEWER'), (now(), now(), 'PL-Operations_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_cmd_JITVIEWER' AND privilege.name IN ( 'jit:PL-Operations:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Operations:cmd:.*:read', 'jit:PL-Operations:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Operations:prod:.*:read'), (now(), now(), 'jit:PL-Operations:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Operations_prod_JITVIEWER'), (now(), now(), 'PL-Operations_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_prod_JITVIEWER' AND privilege.name IN ( 'jit:PL-Operations:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_prod_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Operations:prod:.*:read', 'jit:PL-Operations:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Operations:dev:.*:read'), (now(), now(), 'jit:PL-Operations:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Operations_dev_JITVIEWER'), (now(), now(), 'PL-Operations_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_dev_JITVIEWER' AND privilege.name IN ( 'jit:PL-Operations:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_dev_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Operations:dev:.*:read', 'jit:PL-Operations:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Operations:qa:.*:read'), (now(), now(), 'jit:PL-Operations:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Operations_qa_JITVIEWER'), (now(), now(), 'PL-Operations_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_qa_JITVIEWER' AND privilege.name IN ( 'jit:PL-Operations:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_qa_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Operations:qa:.*:read', 'jit:PL-Operations:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Operations:perf:.*:read'), (now(), now(), 'jit:PL-Operations:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Operations_perf_JITVIEWER'), (now(), now(), 'PL-Operations_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_perf_JITVIEWER' AND privilege.name IN ( 'jit:PL-Operations:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_perf_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Operations:perf:.*:read', 'jit:PL-Operations:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Operations:uat:.*:read'), (now(), now(), 'jit:PL-Operations:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Operations_uat_JITVIEWER'), (now(), now(), 'PL-Operations_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_uat_JITVIEWER' AND privilege.name IN ( 'jit:PL-Operations:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_uat_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Operations:uat:.*:read', 'jit:PL-Operations:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Operations:data-platform-prod:.*:read'), (now(), now(), 'jit:PL-Operations:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Operations_data-platform-prod_JITVIEWER'), (now(), now(), 'PL-Operations_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:PL-Operations:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Operations:data-platform-prod:.*:read', 'jit:PL-Operations:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Operations:data-platform-nonprod:.*:read'), (now(), now(), 'jit:PL-Operations:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Operations_data-platform-nonprod_JITVIEWER'), (now(), now(), 'PL-Operations_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:PL-Operations:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Operations:data-platform-nonprod:.*:read', 'jit:PL-Operations:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Operations:local:.*:read'), (now(), now(), 'jit:PL-Operations:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Operations_local_JITVIEWER'), (now(), now(), 'PL-Operations_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_local_JITVIEWER' AND privilege.name IN ( 'jit:PL-Operations:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_local_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Operations:local:.*:read', 'jit:PL-Operations:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:PL-Operations:.*:.*:read'), (now(), now(), 'jit:PL-Operations:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PL-Operations_ALL_JITVIEWER'), (now(), now(), 'PL-Operations_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_ALL_JITVIEWER' AND privilege.name IN ( 'jit:PL-Operations:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PL-Operations_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:PL-Operations:.*:.*:read', 'jit:PL-Operations:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Post-Purchase-Experience:cmd:.*:read'), (now(), now(), 'jit:Post-Purchase-Experience:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Post-Purchase-Experience_cmd_JITVIEWER'), (now(), now(), 'Post-Purchase-Experience_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:cmd:.*:read', 'jit:Post-Purchase-Experience:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Post-Purchase-Experience:prod:.*:read'), (now(), now(), 'jit:Post-Purchase-Experience:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Post-Purchase-Experience_prod_JITVIEWER'), (now(), now(), 'Post-Purchase-Experience_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_prod_JITVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:prod:.*:read', 'jit:Post-Purchase-Experience:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Post-Purchase-Experience:dev:.*:read'), (now(), now(), 'jit:Post-Purchase-Experience:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Post-Purchase-Experience_dev_JITVIEWER'), (now(), now(), 'Post-Purchase-Experience_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_dev_JITVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:dev:.*:read', 'jit:Post-Purchase-Experience:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Post-Purchase-Experience:qa:.*:read'), (now(), now(), 'jit:Post-Purchase-Experience:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Post-Purchase-Experience_qa_JITVIEWER'), (now(), now(), 'Post-Purchase-Experience_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_qa_JITVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:qa:.*:read', 'jit:Post-Purchase-Experience:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Post-Purchase-Experience:perf:.*:read'), (now(), now(), 'jit:Post-Purchase-Experience:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Post-Purchase-Experience_perf_JITVIEWER'), (now(), now(), 'Post-Purchase-Experience_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_perf_JITVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:perf:.*:read', 'jit:Post-Purchase-Experience:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Post-Purchase-Experience:uat:.*:read'), (now(), now(), 'jit:Post-Purchase-Experience:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Post-Purchase-Experience_uat_JITVIEWER'), (now(), now(), 'Post-Purchase-Experience_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_uat_JITVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:uat:.*:read', 'jit:Post-Purchase-Experience:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Post-Purchase-Experience:data-platform-prod:.*:read'), (now(), now(), 'jit:Post-Purchase-Experience:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Post-Purchase-Experience_data-platform-prod_JITVIEWER'), (now(), now(), 'Post-Purchase-Experience_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:data-platform-prod:.*:read', 'jit:Post-Purchase-Experience:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Post-Purchase-Experience:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Post-Purchase-Experience:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Post-Purchase-Experience_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Post-Purchase-Experience_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:data-platform-nonprod:.*:read', 'jit:Post-Purchase-Experience:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Post-Purchase-Experience:local:.*:read'), (now(), now(), 'jit:Post-Purchase-Experience:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Post-Purchase-Experience_local_JITVIEWER'), (now(), now(), 'Post-Purchase-Experience_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_local_JITVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_local_JITREVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:local:.*:read', 'jit:Post-Purchase-Experience:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Post-Purchase-Experience:.*:.*:read'), (now(), now(), 'jit:Post-Purchase-Experience:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Post-Purchase-Experience_ALL_JITVIEWER'), (now(), now(), 'Post-Purchase-Experience_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Post-Purchase-Experience_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Post-Purchase-Experience:.*:.*:read', 'jit:Post-Purchase-Experience:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:RAndR:cmd:.*:read'), (now(), now(), 'jit:RAndR:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'RAndR_cmd_JITVIEWER'), (now(), now(), 'RAndR_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_cmd_JITVIEWER' AND privilege.name IN ( 'jit:RAndR:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:RAndR:cmd:.*:read', 'jit:RAndR:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:RAndR:prod:.*:read'), (now(), now(), 'jit:RAndR:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'RAndR_prod_JITVIEWER'), (now(), now(), 'RAndR_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_prod_JITVIEWER' AND privilege.name IN ( 'jit:RAndR:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_prod_JITREVIEWER' AND privilege.name IN ( 'jit:RAndR:prod:.*:read', 'jit:RAndR:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:RAndR:dev:.*:read'), (now(), now(), 'jit:RAndR:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'RAndR_dev_JITVIEWER'), (now(), now(), 'RAndR_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_dev_JITVIEWER' AND privilege.name IN ( 'jit:RAndR:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_dev_JITREVIEWER' AND privilege.name IN ( 'jit:RAndR:dev:.*:read', 'jit:RAndR:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:RAndR:qa:.*:read'), (now(), now(), 'jit:RAndR:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'RAndR_qa_JITVIEWER'), (now(), now(), 'RAndR_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_qa_JITVIEWER' AND privilege.name IN ( 'jit:RAndR:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_qa_JITREVIEWER' AND privilege.name IN ( 'jit:RAndR:qa:.*:read', 'jit:RAndR:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:RAndR:perf:.*:read'), (now(), now(), 'jit:RAndR:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'RAndR_perf_JITVIEWER'), (now(), now(), 'RAndR_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_perf_JITVIEWER' AND privilege.name IN ( 'jit:RAndR:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_perf_JITREVIEWER' AND privilege.name IN ( 'jit:RAndR:perf:.*:read', 'jit:RAndR:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:RAndR:uat:.*:read'), (now(), now(), 'jit:RAndR:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'RAndR_uat_JITVIEWER'), (now(), now(), 'RAndR_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_uat_JITVIEWER' AND privilege.name IN ( 'jit:RAndR:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_uat_JITREVIEWER' AND privilege.name IN ( 'jit:RAndR:uat:.*:read', 'jit:RAndR:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:RAndR:data-platform-prod:.*:read'), (now(), now(), 'jit:RAndR:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'RAndR_data-platform-prod_JITVIEWER'), (now(), now(), 'RAndR_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:RAndR:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:RAndR:data-platform-prod:.*:read', 'jit:RAndR:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:RAndR:data-platform-nonprod:.*:read'), (now(), now(), 'jit:RAndR:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'RAndR_data-platform-nonprod_JITVIEWER'), (now(), now(), 'RAndR_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:RAndR:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:RAndR:data-platform-nonprod:.*:read', 'jit:RAndR:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:RAndR:local:.*:read'), (now(), now(), 'jit:RAndR:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'RAndR_local_JITVIEWER'), (now(), now(), 'RAndR_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_local_JITVIEWER' AND privilege.name IN ( 'jit:RAndR:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_local_JITREVIEWER' AND privilege.name IN ( 'jit:RAndR:local:.*:read', 'jit:RAndR:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:RAndR:.*:.*:read'), (now(), now(), 'jit:RAndR:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'RAndR_ALL_JITVIEWER'), (now(), now(), 'RAndR_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_ALL_JITVIEWER' AND privilege.name IN ( 'jit:RAndR:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'RAndR_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:RAndR:.*:.*:read', 'jit:RAndR:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:SDET-Frameworks:cmd:.*:read'), (now(), now(), 'jit:SDET-Frameworks:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'SDET-Frameworks_cmd_JITVIEWER'), (now(), now(), 'SDET-Frameworks_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_cmd_JITVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:cmd:.*:read', 'jit:SDET-Frameworks:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:SDET-Frameworks:prod:.*:read'), (now(), now(), 'jit:SDET-Frameworks:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'SDET-Frameworks_prod_JITVIEWER'), (now(), now(), 'SDET-Frameworks_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_prod_JITVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_prod_JITREVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:prod:.*:read', 'jit:SDET-Frameworks:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:SDET-Frameworks:dev:.*:read'), (now(), now(), 'jit:SDET-Frameworks:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'SDET-Frameworks_dev_JITVIEWER'), (now(), now(), 'SDET-Frameworks_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_dev_JITVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_dev_JITREVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:dev:.*:read', 'jit:SDET-Frameworks:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:SDET-Frameworks:qa:.*:read'), (now(), now(), 'jit:SDET-Frameworks:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'SDET-Frameworks_qa_JITVIEWER'), (now(), now(), 'SDET-Frameworks_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_qa_JITVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_qa_JITREVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:qa:.*:read', 'jit:SDET-Frameworks:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:SDET-Frameworks:perf:.*:read'), (now(), now(), 'jit:SDET-Frameworks:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'SDET-Frameworks_perf_JITVIEWER'), (now(), now(), 'SDET-Frameworks_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_perf_JITVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_perf_JITREVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:perf:.*:read', 'jit:SDET-Frameworks:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:SDET-Frameworks:uat:.*:read'), (now(), now(), 'jit:SDET-Frameworks:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'SDET-Frameworks_uat_JITVIEWER'), (now(), now(), 'SDET-Frameworks_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_uat_JITVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_uat_JITREVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:uat:.*:read', 'jit:SDET-Frameworks:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:SDET-Frameworks:data-platform-prod:.*:read'), (now(), now(), 'jit:SDET-Frameworks:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'SDET-Frameworks_data-platform-prod_JITVIEWER'), (now(), now(), 'SDET-Frameworks_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:data-platform-prod:.*:read', 'jit:SDET-Frameworks:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:SDET-Frameworks:data-platform-nonprod:.*:read'), (now(), now(), 'jit:SDET-Frameworks:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'SDET-Frameworks_data-platform-nonprod_JITVIEWER'), (now(), now(), 'SDET-Frameworks_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:data-platform-nonprod:.*:read', 'jit:SDET-Frameworks:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:SDET-Frameworks:local:.*:read'), (now(), now(), 'jit:SDET-Frameworks:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'SDET-Frameworks_local_JITVIEWER'), (now(), now(), 'SDET-Frameworks_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_local_JITVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_local_JITREVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:local:.*:read', 'jit:SDET-Frameworks:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:SDET-Frameworks:.*:.*:read'), (now(), now(), 'jit:SDET-Frameworks:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'SDET-Frameworks_ALL_JITVIEWER'), (now(), now(), 'SDET-Frameworks_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_ALL_JITVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'SDET-Frameworks_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:SDET-Frameworks:.*:.*:read', 'jit:SDET-Frameworks:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Security:cmd:.*:read'), (now(), now(), 'jit:Security:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Security_cmd_JITVIEWER'), (now(), now(), 'Security_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_cmd_JITVIEWER' AND privilege.name IN ( 'jit:Security:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:Security:cmd:.*:read', 'jit:Security:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Security:prod:.*:read'), (now(), now(), 'jit:Security:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Security_prod_JITVIEWER'), (now(), now(), 'Security_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_prod_JITVIEWER' AND privilege.name IN ( 'jit:Security:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_prod_JITREVIEWER' AND privilege.name IN ( 'jit:Security:prod:.*:read', 'jit:Security:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Security:dev:.*:read'), (now(), now(), 'jit:Security:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Security_dev_JITVIEWER'), (now(), now(), 'Security_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_dev_JITVIEWER' AND privilege.name IN ( 'jit:Security:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_dev_JITREVIEWER' AND privilege.name IN ( 'jit:Security:dev:.*:read', 'jit:Security:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Security:qa:.*:read'), (now(), now(), 'jit:Security:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Security_qa_JITVIEWER'), (now(), now(), 'Security_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_qa_JITVIEWER' AND privilege.name IN ( 'jit:Security:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_qa_JITREVIEWER' AND privilege.name IN ( 'jit:Security:qa:.*:read', 'jit:Security:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Security:perf:.*:read'), (now(), now(), 'jit:Security:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Security_perf_JITVIEWER'), (now(), now(), 'Security_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_perf_JITVIEWER' AND privilege.name IN ( 'jit:Security:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_perf_JITREVIEWER' AND privilege.name IN ( 'jit:Security:perf:.*:read', 'jit:Security:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Security:uat:.*:read'), (now(), now(), 'jit:Security:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Security_uat_JITVIEWER'), (now(), now(), 'Security_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_uat_JITVIEWER' AND privilege.name IN ( 'jit:Security:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_uat_JITREVIEWER' AND privilege.name IN ( 'jit:Security:uat:.*:read', 'jit:Security:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Security:data-platform-prod:.*:read'), (now(), now(), 'jit:Security:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Security_data-platform-prod_JITVIEWER'), (now(), now(), 'Security_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:Security:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:Security:data-platform-prod:.*:read', 'jit:Security:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Security:data-platform-nonprod:.*:read'), (now(), now(), 'jit:Security:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Security_data-platform-nonprod_JITVIEWER'), (now(), now(), 'Security_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:Security:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:Security:data-platform-nonprod:.*:read', 'jit:Security:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Security:local:.*:read'), (now(), now(), 'jit:Security:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Security_local_JITVIEWER'), (now(), now(), 'Security_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_local_JITVIEWER' AND privilege.name IN ( 'jit:Security:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_local_JITREVIEWER' AND privilege.name IN ( 'jit:Security:local:.*:read', 'jit:Security:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:Security:.*:.*:read'), (now(), now(), 'jit:Security:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'Security_ALL_JITVIEWER'), (now(), now(), 'Security_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_ALL_JITVIEWER' AND privilege.name IN ( 'jit:Security:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'Security_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:Security:.*:.*:read', 'jit:Security:.*:.*:review'); + + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:cmd:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:cmd:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_cmd_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_cmd_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_cmd_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:cmd:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_cmd_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:cmd:.*:read', 'jit:UnderwritingAndFraudDetection:cmd:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:prod:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_prod_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_prod_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_prod_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:prod:.*:read', 'jit:UnderwritingAndFraudDetection:prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:dev:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:dev:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_dev_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_dev_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_dev_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:dev:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_dev_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:dev:.*:read', 'jit:UnderwritingAndFraudDetection:dev:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:qa:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:qa:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_qa_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_qa_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_qa_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:qa:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_qa_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:qa:.*:read', 'jit:UnderwritingAndFraudDetection:qa:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:perf:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:perf:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_perf_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_perf_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_perf_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:perf:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_perf_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:perf:.*:read', 'jit:UnderwritingAndFraudDetection:perf:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:uat:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:uat:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_uat_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_uat_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_uat_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:uat:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_uat_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:uat:.*:read', 'jit:UnderwritingAndFraudDetection:uat:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:data-platform-prod:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:data-platform-prod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_data-platform-prod_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_data-platform-prod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_data-platform-prod_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:data-platform-prod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_data-platform-prod_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:data-platform-prod:.*:read', 'jit:UnderwritingAndFraudDetection:data-platform-prod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:data-platform-nonprod:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:data-platform-nonprod:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_data-platform-nonprod_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_data-platform-nonprod_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_data-platform-nonprod_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:data-platform-nonprod:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_data-platform-nonprod_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:data-platform-nonprod:.*:read', 'jit:UnderwritingAndFraudDetection:data-platform-nonprod:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:local:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:local:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_local_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_local_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_local_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:local:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_local_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:local:.*:read', 'jit:UnderwritingAndFraudDetection:local:.*:review'); + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:.*:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_ALL_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_ALL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_ALL_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:.*:.*:read', 'jit:UnderwritingAndFraudDetection:.*:.*:review'); \ No newline at end of file diff --git a/src/main/resources/db/migration/V1.71__Alter_user_table_add_slack_user_id.sql b/src/main/resources/db/migration/V1.71__Alter_user_table_add_slack_user_id.sql new file mode 100644 index 00000000..edd6ba24 --- /dev/null +++ b/src/main/resources/db/migration/V1.71__Alter_user_table_add_slack_user_id.sql @@ -0,0 +1 @@ +ALTER TABLE users ADD COLUMN slack_id character varying(255); From 5a53c2afb376a25610763600a5ada1572e1a9b43 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 21 Mar 2024 16:38:58 +0530 Subject: [PATCH 002/108] INFRA-2219 | Harinder | Adding new slackbotclient --- .../v2/slackbotclient/SlackBotAttachment.java | 23 ++++ .../v2/slackbotclient/SlackBotClient.java | 103 ++++++++++++++++++ .../v2/slackbotclient/SlackBotMessage.java | 22 ++++ .../slackbotclient/SlackBotMessageBlock.java | 55 ++++++++++ .../v2/slackbotclient/SlackElementStyle.java | 14 +++ .../v2/slackbotclient/SlackElementType.java | 13 +++ .../slackbotclient/SlackMessageElement.java | 42 +++++++ 7 files changed, 272 insertions(+) create mode 100644 src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotAttachment.java create mode 100644 src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java create mode 100644 src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessage.java create mode 100644 src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java create mode 100644 src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackElementStyle.java create mode 100644 src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackElementType.java create mode 100644 src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotAttachment.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotAttachment.java new file mode 100644 index 00000000..2cb97bc2 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotAttachment.java @@ -0,0 +1,23 @@ +package com.navi.infra.portal.v2.slackbotclient; + + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.google.gson.JsonElement; +import java.io.Serializable; +import java.util.ArrayList; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@AllArgsConstructor +@Builder(builderClassName = "Builder") +@Getter +@Setter +@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class SlackBotAttachment implements Serializable { + private String color; + private ArrayList blocks; +} diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java new file mode 100644 index 00000000..f2451655 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java @@ -0,0 +1,103 @@ +package com.navi.infra.portal.v2.slackbotclient; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.JsonArray; +import com.slack.api.methods.SlackApiException; +import com.slack.api.model.Attachment; +import com.slack.api.model.User; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.springframework.stereotype.Component; +import org.springframework.beans.factory.annotation.Value; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import com.slack.api.Slack; + + +@Component +@RequiredArgsConstructor +@Slf4j +public class SlackBotClient { + + private static final String SLACK_API_URL = "https://api.slack.com/methods/"; + private static final String postMessage = "chat.postMessage"; + @Value("${slackbot.token}") + private String slackBotToken; + @Value("${slackbot.signing.secret}") + private String slackBotSigningSecret; + + public Map fetchAndProcessSlackUsers() throws IOException { + Map userSlackIdMap = new HashMap<>(); + var client = Slack.getInstance().methods(); + // Slack client reference: https://api.slack.com/methods/users.list/code + + try { + var result = client.usersList(r -> r + .token(slackBotToken) + ); + return updateUserSlackIdMap(result.getMembers(), userSlackIdMap); + } catch (IOException | SlackApiException e) { + log.error("error: {}", e.getMessage(), e); + } + return userSlackIdMap; + } + + private Map updateUserSlackIdMap( + List members, + Map userSlackIdMap + ) { + for (User member : members) { + userSlackIdMap.put(member.getProfile().getEmail(), member.getId()); + } + return userSlackIdMap; + } + + public String postMessage(String channelId, SlackBotAttachment slackBotAttachment) throws IOException { + var client = Slack.getInstance().methods(); + // Slack client reference: https://api.slack.com/methods/chat.postMessage/code + try { + ObjectMapper objectMapper = new ObjectMapper(); + String textJson = "[" + objectMapper.writeValueAsString(slackBotAttachment) + "]"; + var result = client.chatPostMessage(r -> r + .token(slackBotToken) + .channel(channelId) + .text("Just In Time Access Manager") + .attachmentsAsString(textJson) + ); + return result.getTs(); + } catch (IOException | SlackApiException e) { + log.error("error: {}", e.getMessage(), e); + } + return ""; + } + + public String updateMessage(String channelId, SlackBotAttachment slackBotAttachment, String ts) throws IOException { + var client = Slack.getInstance().methods(); + try { + ObjectMapper objectMapper = new ObjectMapper(); + String textJson = "[" + objectMapper.writeValueAsString(slackBotAttachment) + "]"; + var result = client.chatUpdate(r -> r + .token(slackBotToken) + .channel(channelId) + .ts(ts) + .text("Just In Time Access Manager") + .attachmentsAsString(textJson) + ); + return result.getTs(); + } catch (IOException | SlackApiException e) { + log.error("error: {}", e.getMessage(), e); + } + return ""; + } +} diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessage.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessage.java new file mode 100644 index 00000000..e3ed5bb1 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessage.java @@ -0,0 +1,22 @@ +package com.navi.infra.portal.v2.slackbotclient; + + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.navi.infra.portal.dto.slack.SlackMessageBlock; +import java.io.Serializable; +import java.util.ArrayList; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@AllArgsConstructor +@Builder(builderClassName = "Builder") +@Getter +@Setter +@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class SlackBotMessage implements Serializable { + private ArrayList blocks; +} diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java new file mode 100644 index 00000000..edae181e --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java @@ -0,0 +1,55 @@ +package com.navi.infra.portal.v2.slackbotclient; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.navi.infra.portal.dto.slack.SlackMessageBlockType; +import com.navi.infra.portal.dto.slack.SlackMessageText; +import java.util.ArrayList; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class SlackBotMessageBlock { + private String type; // Example: button + private SlackMessageText text; // Should constitute of SlackBotMessageText + private ArrayList elements; + + public SlackBotMessageBlock(SlackMessageBlockType type, SlackMessageText text, ArrayList elements) { + this.type = type.type; + this.text = text; + this.elements = elements; + } + /* + { + "type": "actions", + "elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Status", + "emoji": true + }, + "style": "primary", + "value": "click_me_78", + "action_id": "actionId-2" + }, + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Close", + "emoji": true + }, + "style": "danger", + "value": "click_me_910", + "action_id": "actionId-3" + } + ] + } + */ +} diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackElementStyle.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackElementStyle.java new file mode 100644 index 00000000..0e2e059c --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackElementStyle.java @@ -0,0 +1,14 @@ +package com.navi.infra.portal.v2.slackbotclient; + +public enum SlackElementStyle { + + PRIMARY("primary"), + DANGER("danger"); + + public final String type; + + SlackElementStyle(String type) { + this.type = type; + } + +} \ No newline at end of file diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackElementType.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackElementType.java new file mode 100644 index 00000000..bb4c17ac --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackElementType.java @@ -0,0 +1,13 @@ +package com.navi.infra.portal.v2.slackbotclient; + +public enum SlackElementType { + + BUTTON("button"); + + public final String type; + + SlackElementType(String type) { + this.type = type; + } + +} \ No newline at end of file diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java new file mode 100644 index 00000000..66fce767 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java @@ -0,0 +1,42 @@ +package com.navi.infra.portal.v2.slackbotclient; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.navi.infra.portal.dto.slack.SlackMessageText; +import lombok.Data; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@Data +@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class SlackMessageElement { + private String type; // Example: button + private SlackMessageText text; // Should constitute of SlackMessageText + private String style; // Example: primary, danger + private String value; + private String action_id; // Refers to slackbotclient's interna; action + + public SlackMessageElement(SlackElementType type, SlackMessageText text, SlackElementStyle style, String value, String action_id) { + this.type = type.type; + this.text = text; + this.style = style.type; + this.value = value; + this.action_id = action_id; + } + /* + elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "Approve", + "emoji": true + }, + "style": "primary", + "value": "click_me_123", + "action_id": "actionId-0" + } + ] + */ +} From e5d4be122e826a320f016723ff109d1237a64f9c Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 21 Mar 2024 16:42:25 +0530 Subject: [PATCH 003/108] INFRA-2219 | Harinder | Commiting updates to v2/privilege package --- .../com/navi/infra/portal/v2/privilege/Action.java | 2 ++ .../portal/v2/privilege/PrivilegeServiceImpl.java | 14 +++++++++++--- .../infra/portal/v2/privilege/ResourceType.java | 3 ++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/privilege/Action.java b/src/main/java/com/navi/infra/portal/v2/privilege/Action.java index 9a96d641..db72b89e 100644 --- a/src/main/java/com/navi/infra/portal/v2/privilege/Action.java +++ b/src/main/java/com/navi/infra/portal/v2/privilege/Action.java @@ -16,6 +16,8 @@ public enum Action { APPROVAL_WRITE("approval_write"), MANIFEST_SUBSTITUTE_SECRETS("substitute_secrets"), PORTAL_MANAGE_USERS("manage_users"), + JIT_READERS("read"), + JIT_REVIEWERS("review") ; private final String name; diff --git a/src/main/java/com/navi/infra/portal/v2/privilege/PrivilegeServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/privilege/PrivilegeServiceImpl.java index b20a4762..61ef7d94 100644 --- a/src/main/java/com/navi/infra/portal/v2/privilege/PrivilegeServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/privilege/PrivilegeServiceImpl.java @@ -16,11 +16,15 @@ public class PrivilegeServiceImpl implements PrivilegeService { private final List environmentList; + private final List jitEnvironmentList; + public PrivilegeServiceImpl( PrivilegeRepository repository, - @Value("${environment.list}") List environmentList) { + @Value("${environment.list}") List environmentList, + @Value("${jit.environment.list}") List jitEnvironmentList) { this.repository = repository; this.environmentList = environmentList; + this.jitEnvironmentList = jitEnvironmentList; } @Override @@ -44,7 +48,9 @@ public class PrivilegeServiceImpl implements PrivilegeService { format("manifest:%s:%s:.*:approval_read", teamName, env), format("manifest:%s:%s:.*:delete", teamName, env), format("manifest:%s:%s:.*:manage", teamName, env), - format("manifest:%s:%s:.*:approval_write", teamName, env) + format("manifest:%s:%s:.*:approval_write", teamName, env), + format("jit:%s:%s:.*:read", teamName, env), + format("jit:%s:%s:.*:review", teamName, env) )), Stream.of( format("manifest:%s:.*:.*:read", teamName), format("manifest:%s:.*:.*:write", teamName), @@ -58,7 +64,9 @@ public class PrivilegeServiceImpl implements PrivilegeService { format("manifest:%s:.*:.*:approval_read", teamName), format("manifest:%s:.*:.*:delete", teamName), format("manifest:%s:.*:.*:manage", teamName), - format("manifest:%s:.*:.*:approval_write", teamName) + format("manifest:%s:.*:.*:approval_write", teamName), + format("jit:%s:.*:.*:read", teamName), + format("jit:%s:.*:.*:review", teamName) )); } diff --git a/src/main/java/com/navi/infra/portal/v2/privilege/ResourceType.java b/src/main/java/com/navi/infra/portal/v2/privilege/ResourceType.java index fe5f780f..8ca79711 100644 --- a/src/main/java/com/navi/infra/portal/v2/privilege/ResourceType.java +++ b/src/main/java/com/navi/infra/portal/v2/privilege/ResourceType.java @@ -2,7 +2,8 @@ package com.navi.infra.portal.v2.privilege; public enum ResourceType { MANIFEST, - KUBE; + KUBE, + JIT; @Override public String toString() { From ebb0b13ff4b59dab089332136cbe827cd9082bf4 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 21 Mar 2024 16:43:52 +0530 Subject: [PATCH 004/108] INFRA-2219 | Harinder | Commiting updates to v2/role package --- .../com/navi/infra/portal/v2/role/Actor.java | 6 ++- .../infra/portal/v2/role/RoleRepository.java | 7 +++ .../infra/portal/v2/role/RoleService.java | 6 +++ .../infra/portal/v2/role/RoleServiceImpl.java | 48 +++++++++++++++++-- 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/role/Actor.java b/src/main/java/com/navi/infra/portal/v2/role/Actor.java index a3882f70..197b32fc 100644 --- a/src/main/java/com/navi/infra/portal/v2/role/Actor.java +++ b/src/main/java/com/navi/infra/portal/v2/role/Actor.java @@ -1,9 +1,11 @@ package com.navi.infra.portal.v2.role; -enum Actor { +public enum Actor { VIEWER, MAINTAINER, - MANAGER; + MANAGER, + JITREADER, + JITREVIEWER; @Override public String toString() { diff --git a/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java b/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java index f3e9afde..dc7563e9 100644 --- a/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java @@ -3,6 +3,7 @@ package com.navi.infra.portal.v2.role; import com.navi.infra.portal.domain.user.Role; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @Repository @@ -10,5 +11,11 @@ interface RoleRepository extends JpaRepository { Role findByName(String name); + @Query(value = "SELECT r.id FROM role r WHERE r.name = :name", nativeQuery = true) + Long findIdByName(String name); + List findByNameIn(List name); + + @Query(value = "SELECT rp.privilege_id FROM roles_privileges rp WHERE rp.role_id = :roleId)", nativeQuery = true) + List findAllPrivilegessOfRole(Long roleId); } diff --git a/src/main/java/com/navi/infra/portal/v2/role/RoleService.java b/src/main/java/com/navi/infra/portal/v2/role/RoleService.java index 63f8aca2..d65ade06 100644 --- a/src/main/java/com/navi/infra/portal/v2/role/RoleService.java +++ b/src/main/java/com/navi/infra/portal/v2/role/RoleService.java @@ -9,6 +9,8 @@ public interface RoleService { List findByNameIn(List roles); + Long findIdByName(String role); + List saveAll(List roles); Stream createTeamRoleNames(String teamName); @@ -17,4 +19,8 @@ public interface RoleService { Stream mapPrivilegesToRoles(String teamName, List roles, List privileges); + + List listAllPrivilegesOfRole(Long roleId); + + List listAllAuthorities(List privilegeIds); } diff --git a/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java index e7da3db1..f3b1dfdc 100644 --- a/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java @@ -2,6 +2,8 @@ package com.navi.infra.portal.v2.role; import static com.navi.infra.portal.v2.privilege.Action.APPROVAL_READ; import static com.navi.infra.portal.v2.privilege.Action.APPROVAL_WRITE; +import static com.navi.infra.portal.v2.privilege.Action.JIT_READERS; +import static com.navi.infra.portal.v2.privilege.Action.JIT_REVIEWERS; import static com.navi.infra.portal.v2.privilege.Action.KUBE_DELETE; import static com.navi.infra.portal.v2.privilege.Action.KUBE_RESTART; import static com.navi.infra.portal.v2.privilege.Action.MANIFEST_CLONE; @@ -13,8 +15,11 @@ import static com.navi.infra.portal.v2.privilege.Action.MANIFEST_SECRET_WRITE; import static com.navi.infra.portal.v2.privilege.Action.MANIFEST_SUPERSECRET_WRITE; import static com.navi.infra.portal.v2.privilege.Action.MANIFEST_WRITE; import static com.navi.infra.portal.v2.privilege.PrivilegeService.ALL; +import static com.navi.infra.portal.v2.privilege.ResourceType.JIT; import static com.navi.infra.portal.v2.privilege.ResourceType.KUBE; import static com.navi.infra.portal.v2.privilege.ResourceType.MANIFEST; +import static com.navi.infra.portal.v2.role.Actor.JITREADER; +import static com.navi.infra.portal.v2.role.Actor.JITREVIEWER; import static com.navi.infra.portal.v2.role.Actor.MAINTAINER; import static com.navi.infra.portal.v2.role.Actor.MANAGER; import static com.navi.infra.portal.v2.role.Actor.VIEWER; @@ -38,9 +43,13 @@ import java.util.Optional; import java.util.stream.Stream; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; @Service +@Primary +@Component("DefaultRoleService") class RoleServiceImpl implements RoleService { private static final String ALL_ENV = "ALL"; @@ -67,6 +76,17 @@ class RoleServiceImpl implements RoleService { return repository.findByNameIn(roles); } + @Override + public Long findIdByName(String role) { + return repository.findIdByName(role); + } + + public List listAllPrivilegesOfRole(Long roleId){ + return repository.findAllPrivilegessOfRole(roleId); + } + + public List listAllAuthorities(List privilegeIds) { return null; } + @Override public List saveAll(List roles) { return repository.saveAll(roles); @@ -78,11 +98,15 @@ class RoleServiceImpl implements RoleService { .flatMap(env -> Stream.of( generateName(teamName, env, VIEWER), generateName(teamName, env, MAINTAINER), - generateName(teamName, env, MANAGER) + generateName(teamName, env, MANAGER), + generateName(teamName, env, JITREADER), + generateName(teamName, env, JITREVIEWER) )), Stream.of( generateName(teamName, ALL_ENV, VIEWER), generateName(teamName, ALL_ENV, MAINTAINER), - generateName(teamName, ALL_ENV, MANAGER) + generateName(teamName, ALL_ENV, MANAGER), + generateName(teamName, ALL_ENV, JITREADER), + generateName(teamName, ALL_ENV, JITREVIEWER) )); } @@ -113,6 +137,7 @@ class RoleServiceImpl implements RoleService { .flatMap(List::stream); } + private List mapPrivilegesToRoles( String teamName, String env, @@ -138,7 +163,9 @@ class RoleServiceImpl implements RoleService { return Map.of( generateName(teamName, env, VIEWER), viewerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), generateName(teamName, env, MAINTAINER), maintainerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), - generateName(teamName, env, MANAGER), managerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)) + generateName(teamName, env, MANAGER), managerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), + generateName(teamName, env, JITREADER), jitViewerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), + generateName(teamName, env, JITREVIEWER), jitReviewerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)) ); } @@ -173,6 +200,21 @@ class RoleServiceImpl implements RoleService { privilegeService.generateName(MANIFEST, teamName, env, ALL, MANIFEST_READ)); } + private List jitViewerPrivileges(String teamName, String env) { + return List.of( + privilegeService.generateName(JIT, teamName, env, ALL, JIT_READERS)); + } + + private List jitReviewerPrivileges(String teamName, String env) { + final var privileges = new ArrayList<>(jitViewerPrivileges(teamName, env)); + privileges.addAll( + List.of( + privilegeService.generateName(JIT, teamName, env, ALL, JIT_REVIEWERS) + )); + return unmodifiableList(privileges); + } + + private String generateName(String teamName, String env, Actor actor) { return join(List.of(teamName, env, actor), '_'); } From 14a6dbd6d35663021a9cb6416d88f4ae693047f6 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 21 Mar 2024 16:44:37 +0530 Subject: [PATCH 005/108] INFRA-2219 | Harinder | Adding changes done to TeamConfiguration --- .../navi/infra/portal/configuration/TeamConfiguration.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/navi/infra/portal/configuration/TeamConfiguration.java b/src/main/java/com/navi/infra/portal/configuration/TeamConfiguration.java index 0010f80b..c68eb31f 100644 --- a/src/main/java/com/navi/infra/portal/configuration/TeamConfiguration.java +++ b/src/main/java/com/navi/infra/portal/configuration/TeamConfiguration.java @@ -21,6 +21,8 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -31,7 +33,8 @@ import org.springframework.transaction.annotation.Transactional; public class TeamConfiguration { private final TeamRepository teamRepository; - + @Autowired + @Qualifier(value = "DefaultRoleService") private final RoleService roleService; private final PrivilegeService privilegeService; From 8389fac1cf97edb27add3d7ae0b2bd610035923a Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 21 Mar 2024 16:48:31 +0530 Subject: [PATCH 006/108] INFRA-2219 | Harinder | Accessing repositories via service(user, role, team, cluster). Adding slackId to User Entity --- .../navi/infra/portal/domain/user/User.java | 2 + .../portal/repository/UserRepository.java | 20 +++++- .../portal/service/user/UserService.java | 64 ++++++++++++++++--- .../repository/ClusterRepository.java | 1 + .../infra/portal/v2/team/TeamService.java | 2 + .../infra/portal/v2/team/TeamServiceImpl.java | 8 +++ .../portal/service/user/UserServiceTest.java | 3 +- .../portal/v2/role/RoleServiceImplTest.java | 6 +- 8 files changed, 91 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/domain/user/User.java b/src/main/java/com/navi/infra/portal/domain/user/User.java index d4a72342..cbfa48fa 100644 --- a/src/main/java/com/navi/infra/portal/domain/user/User.java +++ b/src/main/java/com/navi/infra/portal/domain/user/User.java @@ -38,6 +38,8 @@ public class User extends BaseEntity implements AuthenticatedUser { private String email; + private String slackId; + @OneToOne(mappedBy = "user") private Token token; diff --git a/src/main/java/com/navi/infra/portal/repository/UserRepository.java b/src/main/java/com/navi/infra/portal/repository/UserRepository.java index 5aaf3e35..7e352f6a 100644 --- a/src/main/java/com/navi/infra/portal/repository/UserRepository.java +++ b/src/main/java/com/navi/infra/portal/repository/UserRepository.java @@ -9,10 +9,28 @@ import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository { - @Query("SELECT u FROM User u WHERE lower(u.email) = :email") Optional findByEmail(String email); + @Query("SELECT u FROM User u WHERE lower(u.email) = :email") + User findUserByEmail(String email); + + @Query("SELECT u.id FROM User u WHERE lower(u.email) = :email") + Long findIdByEmail(String email); + @Query("SELECT u FROM User u WHERE lower(u.email) in (:emailList)") List> findAllByEmail(List emailList); + + @Query(value = "SELECT ur.user_id FROM users_roles ur WHERE ur.role_id = :roleId", nativeQuery = true) + List findUserIdsByRoleIds(Long roleId); + + @Query(value = "SELECT ur.role_id FROM users_roles ur WHERE ur.user_id = :userId)", nativeQuery = true) + List findAllRolesOfUser(Long userId); + + @Query(value = "SELECT u FROM users u WHERE u.id IN = :roleId)", nativeQuery = true) + User findUsersByRoleName(Long roleId); + + + @Query(value = "SELECT u.slack_id FROM users u WHERE lower(u.email) = :email", nativeQuery = true) + Optional findSlackId(String email); } diff --git a/src/main/java/com/navi/infra/portal/service/user/UserService.java b/src/main/java/com/navi/infra/portal/service/user/UserService.java index 85d750a4..14035a5c 100644 --- a/src/main/java/com/navi/infra/portal/service/user/UserService.java +++ b/src/main/java/com/navi/infra/portal/service/user/UserService.java @@ -24,14 +24,17 @@ import com.navi.infra.portal.repository.TokenRepository; import com.navi.infra.portal.repository.UserRepository; import com.navi.infra.portal.security.authorization.AuthorizationContext; import com.navi.infra.portal.v2.role.RoleService; +import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; import com.navi.infra.portal.v2.team.TeamService; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import java.util.stream.Stream; import javassist.NotFoundException; import lombok.extern.slf4j.Slf4j; @@ -63,6 +66,8 @@ public class UserService { private final ObjectMapper yamlMapper; + private final SlackBotClient slackBotClient; + public UserService( UserRepository userRepository, RoleService roleService, @@ -71,7 +76,8 @@ public class UserService { PasswordEncoder passwordEncoder, TeamService teamService, @Qualifier("jsonMapper") ObjectMapper objectMapper, - @Qualifier("yamlMapper") ObjectMapper yamlMapper + @Qualifier("yamlMapper") ObjectMapper yamlMapper, + SlackBotClient slackBotClient ) { this.userRepository = userRepository; this.roleService = roleService; @@ -81,6 +87,7 @@ public class UserService { this.teamService = teamService; this.objectMapper = objectMapper; this.yamlMapper = yamlMapper; + this.slackBotClient = slackBotClient; } private static boolean filterUnsavedUsers( @@ -136,15 +143,17 @@ public class UserService { public User from(OidcUser oidcUser) { final String email = oidcUser.getEmail(); final var userOptional = userRepository.findByEmail(email); - var user = userOptional.orElseThrow( - () -> new OAuth2AuthenticationException(new OAuth2Error("0", "Create your entry in https://github.com/navi-infra/user-management/blob/master/deployment-portal/user-mapping.yaml", "/")) - ); - if (user.getName() == null && oidcUser.getAttribute("name") != null) { - user.setName(oidcUser.getAttribute("name")); - log.info("User {} has no name, setting name to {}", email, user.getName()); - user = userRepository.save(user); - } - return user; + var user = userOptional.orElseThrow( + () -> new OAuth2AuthenticationException(new OAuth2Error("0", + "Create your entry in https://github.com/navi-infra/user-management/blob/master/deployment-portal/user-mapping.yaml", + "/")) + ); + if (user.getName() == null && oidcUser.getAttribute("name") != null) { + user.setName(oidcUser.getAttribute("name")); + log.info("User {} has no name, setting name to {}", email, user.getName()); + user = userRepository.save(user); + } + return user; } // if token already exist it will replace the token @@ -302,4 +311,39 @@ public class UserService { }) .collect(toList()); } + + public User findUserByEmail(String email) { + return userRepository.findUserByEmail(email); + } + + public List getUsersWithRole(String roleName) { + Long roleId = roleService.findIdByName(roleName); + List userIds = userRepository.findUserIdsByRoleIds(roleId); + return userRepository.findAllById(userIds); + } + + public List listAllRolesOfUser(Long userId) { + return userRepository.findAllRolesOfUser(userId); + } + + public List listAllRolesOfUser(String email) { + Long id = userRepository.findIdByEmail(email); + return userRepository.findAllRolesOfUser(id); + } + + public String getSlackId(String email) throws IOException { + Optional slackId = userRepository.findSlackId(email); + if (!slackId.isPresent()){ + var users = userRepository.findAll(); + Map emailSlackIdMapping = slackBotClient.fetchAndProcessSlackUsers(); + users.forEach(user -> { + if (user.getSlackId() == null || user.getSlackId().isEmpty()){ + user.setSlackId(emailSlackIdMapping.get(user.getEmail())); + } + }); + userRepository.saveAll(users); + return getSlackId(email); + } + return slackId.get(); + } } diff --git a/src/main/java/com/navi/infra/portal/v2/grafanadashboard/repository/ClusterRepository.java b/src/main/java/com/navi/infra/portal/v2/grafanadashboard/repository/ClusterRepository.java index 046e18b5..81cc9f9b 100644 --- a/src/main/java/com/navi/infra/portal/v2/grafanadashboard/repository/ClusterRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/grafanadashboard/repository/ClusterRepository.java @@ -3,6 +3,7 @@ package com.navi.infra.portal.v2.grafanadashboard.repository; import com.navi.infra.portal.v2.grafanadashboard.entity.Cluster; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; diff --git a/src/main/java/com/navi/infra/portal/v2/team/TeamService.java b/src/main/java/com/navi/infra/portal/v2/team/TeamService.java index 7d2cadb8..d7a3cd50 100644 --- a/src/main/java/com/navi/infra/portal/v2/team/TeamService.java +++ b/src/main/java/com/navi/infra/portal/v2/team/TeamService.java @@ -14,5 +14,7 @@ public interface TeamService { List findByNames(List names); + Team findByName(String name); + List findAllByIds(List ids); } diff --git a/src/main/java/com/navi/infra/portal/v2/team/TeamServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/team/TeamServiceImpl.java index e5bbc433..494255b7 100644 --- a/src/main/java/com/navi/infra/portal/v2/team/TeamServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/team/TeamServiceImpl.java @@ -36,8 +36,16 @@ public class TeamServiceImpl implements TeamService { return repository.findByNameIn(names); } + @Override + public Team findByName(String name) { + Optional team = repository.findByName(name); + return team.orElseGet(Team::new); + } + @Override public List findAllByIds(List ids) { return repository.findAllById(ids); } + + } diff --git a/src/test/java/com/navi/infra/portal/service/user/UserServiceTest.java b/src/test/java/com/navi/infra/portal/service/user/UserServiceTest.java index 64a9d547..90ea13ff 100644 --- a/src/test/java/com/navi/infra/portal/service/user/UserServiceTest.java +++ b/src/test/java/com/navi/infra/portal/service/user/UserServiceTest.java @@ -53,7 +53,8 @@ class UserServiceTest { null, teamService, null, - yamlMapper + yamlMapper, + null ); } diff --git a/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java index 8d270ce3..ad222f13 100644 --- a/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java @@ -29,7 +29,7 @@ class RoleServiceImplTest { ); roleServiceImpl = new RoleServiceImpl( null, - new PrivilegeServiceImpl(null, environmentList), + new PrivilegeServiceImpl(null, environmentList, environmentList), environmentList, rolePrivilegesEnvMap); @@ -93,8 +93,8 @@ class RoleServiceImplTest { null); var teamName = "team"; var actual = roleServiceImpl.createTeamRoleNames(teamName).collect(toList()); - var expected = List.of("team_dev_VIEWER", "team_dev_MAINTAINER", "team_dev_MANAGER", - "team_ALL_VIEWER", "team_ALL_MAINTAINER", "team_ALL_MANAGER"); + var expected = List.of("team_dev_VIEWER", "team_dev_MAINTAINER", "team_dev_MANAGER", "team_dev_JITREADER, team_dev_JITREVIEWER", + "team_ALL_VIEWER", "team_ALL_MAINTAINER", "team_ALL_MANAGER", "team_ALL_JITREADER, team_ALL_JITREVIEWER"); assertEquals(expected, actual); } From 2d7127f0336a0731030eec9b4bae2868eda0a867 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 21 Mar 2024 16:51:59 +0530 Subject: [PATCH 007/108] INFRA-2219 | Harinder | Adding changes to existing slackClient's entities that are being reused --- .../portal/dto/slack/SlackMessageBlockType.java | 3 ++- .../infra/portal/dto/slack/SlackMessageText.java | 13 +++++++++++++ .../portal/dto/slack/SlackMessageTextType.java | 14 ++++++++++++++ .../infra/portal/events/PortalEventListener.java | 7 ++++--- 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/navi/infra/portal/dto/slack/SlackMessageTextType.java diff --git a/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageBlockType.java b/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageBlockType.java index bfc57860..8f8d7832 100644 --- a/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageBlockType.java +++ b/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageBlockType.java @@ -5,7 +5,8 @@ public enum SlackMessageBlockType { CONTEXT("context"), DIVIDER("divider"), HEADER("header"), - SECTION("section"); + SECTION("section"), + ACTIONS("actions"); public final String type; diff --git a/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageText.java b/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageText.java index 590b7f9c..4e63e909 100644 --- a/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageText.java +++ b/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageText.java @@ -13,4 +13,17 @@ public class SlackMessageText { private String type; private String text; + + public SlackMessageText(SlackMessageTextType type, String text) { + this.type = type.type; + this.text = text; + } + + /* + "text": { + "type": "plain_text", + "text": "Reject", + "emoji": true + } + */ } diff --git a/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageTextType.java b/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageTextType.java new file mode 100644 index 00000000..dbdf13bb --- /dev/null +++ b/src/main/java/com/navi/infra/portal/dto/slack/SlackMessageTextType.java @@ -0,0 +1,14 @@ +package com.navi.infra.portal.dto.slack; + +public enum SlackMessageTextType { + + MARKDOWN("mrkdwn"), + PLAINTEXT("plain_text"); + + public final String type; + + SlackMessageTextType(String type) { + this.type = type; + } + +} diff --git a/src/main/java/com/navi/infra/portal/events/PortalEventListener.java b/src/main/java/com/navi/infra/portal/events/PortalEventListener.java index d9c70109..512a7532 100644 --- a/src/main/java/com/navi/infra/portal/events/PortalEventListener.java +++ b/src/main/java/com/navi/infra/portal/events/PortalEventListener.java @@ -15,6 +15,7 @@ import com.navi.infra.portal.dto.slack.SlackMessage; import com.navi.infra.portal.dto.slack.SlackMessageBlock; import com.navi.infra.portal.dto.slack.SlackMessageBlockType; import com.navi.infra.portal.dto.slack.SlackMessageText; +import com.navi.infra.portal.dto.slack.SlackMessageTextType; import com.navi.infra.portal.util.MapDiffUtil; import java.util.ArrayList; import java.util.List; @@ -89,7 +90,7 @@ public class PortalEventListener { ArrayList list = new ArrayList<>(); SlackMessageText majorText = new SlackMessageText(); - majorText.setType("plain_text"); + majorText.setType(SlackMessageTextType.PLAINTEXT.type); majorText.setText(format(vaultUpdateEvent.getMessage())); SlackMessageBlock majorTextBlock = new SlackMessageBlock(); majorTextBlock.setType(SlackMessageBlockType.HEADER.type); @@ -195,9 +196,9 @@ public class PortalEventListener { private SlackMessageBlock getSlackMessageBlock(SlackMessageBlockType blockType, String message) { SlackMessageText slackMessageText = new SlackMessageText(); - String textType = "mrkdwn"; + String textType = SlackMessageTextType.MARKDOWN.type; if (blockType.type.equals(SlackMessageBlockType.HEADER.type)) { - textType = "plain_text"; + textType = SlackMessageTextType.PLAINTEXT.type; } slackMessageText.setType(textType); slackMessageText.setText(message); From a055dd18899d275b51a19cc0f666afd6dc57f486 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 22 Mar 2024 17:05:58 +0530 Subject: [PATCH 008/108] INFRA-2219 | Harinder | Modularizing code, updating repository code, airflowclient after testing, slackbotclient --- pom.xml | 5 + .../v2/client/airflow/AirflowClient.java | 42 ++ .../repository/JitApprovalsRepository.java | 4 +- .../jit/repository/JitRequestsRepository.java | 6 +- .../portal/v2/jit/service/JitServiceImpl.java | 420 +++++++----------- .../infra/portal/v2/jit/utils/AuthUtil.java | 88 ++++ .../portal/v2/jit/utils/SlackBotUtil.java | 123 +++++ .../portal/v2/jit/utils/validateRequest.java | 4 - .../v2/privilege/PrivilegeServiceImpl.java | 6 +- .../v2/slackbotclient/SlackBotClient.java | 37 +- ...V1.68__Add_just_in_time_requests_table.sql | 2 +- ...1.69__Add_just_in_time_approvals_table.sql | 2 +- .../portal/v2/role/RoleServiceImplTest.java | 2 +- 13 files changed, 442 insertions(+), 299 deletions(-) create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java delete mode 100644 src/main/java/com/navi/infra/portal/v2/jit/utils/validateRequest.java diff --git a/pom.xml b/pom.xml index d75b99ab..27c3019c 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,11 @@ + + com.slack.api + slack-api-client + 1.38.3 + com.flipkart.zjsonpatch zjsonpatch diff --git a/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java b/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java index bdcbecb6..bc91b586 100644 --- a/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java +++ b/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java @@ -5,10 +5,14 @@ import static java.lang.String.format; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.v2.dump.DumpTriggerRequest; +import com.navi.infra.portal.v2.jit.entity.JitRequest; import java.net.URI; +import java.time.ZoneId; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; @@ -86,6 +90,44 @@ public class AirflowClient { } } + public AirflowApiResponse triggerJitDag(JitRequest jitRequest, String dagId, String runId, String action) { +// Date execution_date = action.equals("grant")? jitRequest.getGrantAt() : Date.from(jitRequest.getGrantAt().toInstant().plusSeconds(60*jitRequest.getGrantWindow())); + LocalDateTime executionDate = action.equals("grant")? jitRequest.getGrantAt() : jitRequest.getGrantAt().plusHours(jitRequest.getGrantWindow()); + var payloadMap = Map.of( //"dag_run_id", runId, + "execution_date", String.join("+",executionDate.toString(),"05:30"), + "conf", Map.of( + "vertical", jitRequest.getVertical().toString(), + "team", jitRequest.getTeam().getName(), + "env", jitRequest.getEnvironment().toString(), + "resource_type", jitRequest.getResourceType(), + "resource_id", jitRequest.getResourceId(), + "user", jitRequest.getRequestedFor().getEmail(), + "resource_action", jitRequest.getResourceAction(), + "action", action + )); + + var grantPayload = convertMapToString(payloadMap); + try { + var client = HttpClient.newHttpClient(); + var request = HttpRequest.newBuilder() + .uri(dagRunUri(dagId)) + .header("Cache-Control", "no-cache") + .header("Content-Type", "application/json") + .header("Authorization", "Basic " + this.authToken) + .POST(HttpRequest.BodyPublishers.ofString(grantPayload)) + .build(); + + log.info("Triggering JIT DAG for runId: {}", runId); + var response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + return objectMapper.readValue(response.body(), + AirflowApiResponse.class); + } catch (Exception e) { + log.error(e.getMessage()); + throw new RuntimeException("Failed to connect to airflow", e.getCause()); + } + } + private String convertMapToString(Map payloadMap) { String payload; try { diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java index 93526313..2912a758 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java @@ -11,12 +11,12 @@ public interface JitApprovalsRepository extends JpaRepository @Query(value = "SELECT ja.reviewer_id FROM jit_approvals ja WHERE ja.id = :id", nativeQuery = true) String findReviewerId(Long id); - @Query(value = "SELECT ja FROM jit_approvals ja WHERE ja.id = :jit_id", nativeQuery = true) + @Query(value = "SELECT ja.* FROM jit_approvals ja WHERE ja.jit_id = :jit_id", nativeQuery = true) List findAllReviewsByJitId(Long jit_id); @Query(value="SELECT COUNT(ja.reviewer_id) FROM jit_approvals ja WHERE ja.jit_id = :jit_id", nativeQuery = true) Long findApprovedRequestsCount(Long jit_id); - @Query(value="SELECT ja.reviewer_id FROM jit_approvals ja WHERE ja.jit_id = :jit_id and lower(ja.action) = :action", nativeQuery = true) + @Query(value="SELECT ja.reviewer_id FROM jit_approvals ja WHERE ja.jit_id = :jit_id and ja.action = :action", nativeQuery = true) List findReviewersByAction(Long jit_id, String action); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java index 9c5f8fa5..b4c6fe1d 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java @@ -2,11 +2,13 @@ package com.navi.infra.portal.v2.jit.repository; import com.navi.infra.portal.v2.jit.entity.JitRequest; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @Repository public interface JitRequestsRepository extends JpaRepository { - @Query(value = "UPDATE jit_requests jr SET jr.status=CANCELLED WHERE ja.id = :jit_id", nativeQuery = true) - void updateRequestStatus(Long jit_id); + @Modifying + @Query(value = "UPDATE jit_requests SET status = :action WHERE id = :jit_id", nativeQuery = true) + void updateRequestStatus(Long jit_id, String action); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 51ccc72c..864980db 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -4,9 +4,6 @@ import static com.navi.infra.portal.v2.role.Actor.JITREVIEWER; import com.navi.infra.portal.domain.user.Role; import com.navi.infra.portal.domain.user.User; -import com.navi.infra.portal.dto.slack.SlackMessageBlockType; -import com.navi.infra.portal.dto.slack.SlackMessageText; -import com.navi.infra.portal.dto.slack.SlackMessageTextType; import com.navi.infra.portal.service.user.UserService; import com.navi.infra.portal.v2.client.airflow.AirflowClient; import com.navi.infra.portal.v2.jit.dto.JitRequestDTO; @@ -17,151 +14,119 @@ import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; import com.navi.infra.portal.v2.jit.repository.JitRequestsRepository; +import com.navi.infra.portal.v2.jit.utils.AuthUtil; +import com.navi.infra.portal.v2.jit.utils.SlackBotUtil; import com.navi.infra.portal.v2.privilege.ResourceType; import com.navi.infra.portal.v2.role.RoleService; import com.navi.infra.portal.v2.slackbotclient.SlackBotAttachment; import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; -import com.navi.infra.portal.v2.slackbotclient.SlackBotMessageBlock; -import com.navi.infra.portal.v2.slackbotclient.SlackElementStyle; -import com.navi.infra.portal.v2.slackbotclient.SlackElementType; -import com.navi.infra.portal.v2.slackbotclient.SlackMessageElement; import com.navi.infra.portal.v2.team.TeamService; import java.io.IOException; import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service +@RequiredArgsConstructor @Slf4j public class JitServiceImpl implements JitService { + private final JitRequestsRepository jitRequestRepository; + private final JitApprovalsRepository jitApprovalsRepository; + private final SlackBotUtil slackBotUtil; + private final AuthUtil authUtil; + private final AirflowClient airflowClient; private final SlackBotClient slackBotClient; + private final UserService userService; private final RoleService roleService; private final TeamService teamService; - private final JitRequestsRepository jitRequestRepository; - private final JitApprovalsRepository jitApprovalsRepository; + private final ResourceType resourceType = null; private final String env = null; - @Value("${jit.number_of_prod_approvals}") - private final Long prodJitApprovalsCount; - @Value("${jit.number_of_nonprod_approvals}") - private final Long nonprodJitApprovalsCount; + @Value("${jit.dag.id}") - private final String dagId; + private String dagId; @Value("${jit.slack.common.channel.id}") - private final String commonChannelId; + private String commonChannelId; - public JitServiceImpl( - AirflowClient airflowClient, - SlackBotClient slackBotClient, - UserService userService, - RoleService roleService, - TeamService teamService, - JitRequestsRepository jitRequestRepository, - JitApprovalsRepository jitApprovalsRepository, - @Value("${jit.dag.id}") String dagId, - @Value("${jit.number_of_prod_approvals}") Long prodJitApprovalsCount, - @Value("${jit.number_of_nonprod_approvals}") Long nonprodJitApprovalsCount, - String commonChannelId - ) { - this.airflowClient = airflowClient; - this.slackBotClient = slackBotClient; - this.userService = userService; - this.roleService = roleService; - this.teamService = teamService; - this.jitRequestRepository = jitRequestRepository; - this.jitApprovalsRepository = jitApprovalsRepository; - this.dagId = dagId; - this.prodJitApprovalsCount = prodJitApprovalsCount; - this.nonprodJitApprovalsCount = nonprodJitApprovalsCount; - this.commonChannelId = commonChannelId; - } - - private Boolean checkRequiredApprovals(JitRequest jitRequest) { - Environment env = jitRequest.getEnvironment(); - Long approvedRequests = jitApprovalsRepository.findApprovedRequestsCount( - jitRequest.getId()); - if ((env.equals(Environment.PROD) || env.equals(Environment.CMD) || env.equals( - Environment.DATA_PLATFORM_PROD)) && approvedRequests >= prodJitApprovalsCount) { - return true; - } else if ((env.equals(Environment.NONPROD) || env.equals(Environment.DEV) || env.equals( - Environment.QA) || env.equals(Environment.DATA_PLATFORM_NONPROD) || env.equals( - Environment.UAT) || env.equals(Environment.PERF)) - && approvedRequests >= nonprodJitApprovalsCount) { - return true; - } - return false; - } - - private boolean isAuthorized(String user, JitRequest jitRequest) { - List userRolesId = userService.listAllRolesOfUser(user); - List userRoles = roleService.listAllAuthorities(userRolesId); - - return userRoles.stream().filter( - role -> role.contains(JITREVIEWER.toString()) && role.contains( - jitRequest.getTeam().getName())).anyMatch( - role -> role.contains(jitRequest.getEnvironment().toString()) || role.contains("ALL")); - } - - private List getReviewersByAction( - UserService userService, Long jitId, JitRequestStatus jitRequestStatus - ) { - return userService.findAllByIds( - jitApprovalsRepository.findReviewersByAction(jitId, jitRequestStatus.toString())) - .parallelStream().map(User::getEmail).collect(Collectors.toList()); - } - - private void updateReviewerMessageOnSlack(User reviewer, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled) + private void updateReviewerMessageOnSlack( + User reviewer, + JitRequest jitRequest, + JitApproval jitApproval, + boolean actionEnabled + ) throws IOException { - SlackBotAttachment reviewMessage = getReviewerMessage( + SlackBotAttachment reviewMessage = slackBotUtil.getReviewerMessage( jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled); String messageTimestamp = slackBotClient.postMessage( userService.getSlackId(reviewer.getEmail()), reviewMessage); jitApproval.setSlackMessageTimestamp(messageTimestamp); + + jitApprovalsRepository.save(jitApproval); } - private void updatePersonalMessageOnSlack(JitRequest jitRequest, List pendingReviewers, List approvedReviewers, List rejectedReviewers, boolean actionEnabled) + private JitRequest updatePersonalMessageOnSlack( + JitRequest jitRequest, + List pendingReviewers, + List approvedReviewers, + List rejectedReviewers, + boolean actionEnabled + ) throws IOException { - SlackBotAttachment personalMessage = getPersonalMessage( + SlackBotAttachment personalMessage = slackBotUtil.getPersonalMessage( jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingReviewers, approvedReviewers, rejectedReviewers, jitRequest.getStatus().toString()); String messageTimestamp = slackBotClient.postMessage( userService.getSlackId(jitRequest.getRequestedBy().getEmail()), personalMessage); jitRequest.setPersonalSlackMessageTimestamp(messageTimestamp); + return jitRequest; } - private void updateGroupMessageOnSlack(JitRequest jitRequest, List pendingReviewers, List approvedReviewers, List rejectedReviewers) + private JitRequest updateGroupMessageOnSlack( + JitRequest jitRequest, + List pendingReviewers, + List approvedReviewers, + List rejectedReviewers + ) throws IOException { - SlackBotAttachment commonChannelMessage = getGroupMessage(jitRequest, - jitRequest.getRequestedFor().getEmail(), pendingReviewers, approvedReviewers, rejectedReviewers); + SlackBotAttachment commonChannelMessage = slackBotUtil.getGroupMessage(jitRequest, + jitRequest.getRequestedFor().getEmail(), pendingReviewers, approvedReviewers, + rejectedReviewers); String messageTimestamp = slackBotClient.postMessage(commonChannelId, commonChannelMessage); jitRequest.setGroupSlackMessageTimestamp(messageTimestamp); + return jitRequest; } private Integer processJitRequest( - String reviewerEmail, Long requestId, JitFlowFunction flowFunction + String reviewerEmail, + Long requestId, + JitRequestStatus jitRequestStatus, + JitFlowFunction flowFunction ) throws IOException { Optional jA = jitApprovalsRepository.findById(requestId); if (jA.isPresent()) { JitApproval jitApproval = jA.get(); - if (jitApproval.getReviewedAt() != null) { + JitRequest jitRequest = jitApproval.getJitRequest(); + if (jitApproval.getReviewedAt() != null || !jitRequest.getStatus() + .equals(JitRequestStatus.PENDING)) { log.error("Request already reviewed"); return -1; } jitApproval.setReviewedAt(LocalDateTime.now()); - JitRequest jitRequest = jitApproval.getJitRequest(); - if (!reviewerEmail.equals(jitApproval.getReviewer().getEmail()) && !isAuthorized( + if (!reviewerEmail.equals(jitApproval.getReviewer().getEmail()) + && !authUtil.isAuthorized( reviewerEmail, jitRequest) && reviewerEmail.equals( jitRequest.getRequestedFor().getEmail())) { log.error("User {} not allowed to perform action", reviewerEmail); @@ -169,47 +134,62 @@ public class JitServiceImpl implements JitService { } jitApproval.setReviewer(userService.findUserByEmail(reviewerEmail)); - return flowFunction.apply(reviewerEmail, jitApproval, jitRequest); + jitApproval.setAction(jitRequestStatus); + + List pendingReviewers = authUtil.getReviewersByAction(userService, + jitRequest.getId(), + JitRequestStatus.PENDING); + List approvedReviewers = authUtil.getReviewersByAction(userService, + jitRequest.getId(), + JitRequestStatus.APPROVED); + List rejectedReviewers = authUtil.getReviewersByAction(userService, + jitRequest.getId(), + JitRequestStatus.REJECTED); + + return flowFunction.apply(reviewerEmail, jitApproval, jitRequest, pendingReviewers, + approvedReviewers, rejectedReviewers); } log.error("Illegal request"); return -1; } private Integer jitApprovedFlow( - String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest + String reviewerEmail, + JitApproval jitApproval, + JitRequest jitRequest, + List pendingReviewers, + List approvedReviewers, + List rejectedReviewers ) throws IOException { try { - jitApprovalsRepository.save(jitApproval); - - List pendingReviewers = getReviewersByAction(userService, jitRequest.getId(), - JitRequestStatus.PENDING); - List approvedReviewers = getReviewersByAction(userService, jitRequest.getId(), - JitRequestStatus.APPROVED); - List rejectedReviewers = getReviewersByAction(userService, jitRequest.getId(), - JitRequestStatus.REJECTED); - - // inform reviewer on slack that request is approved and remove action buttons - updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); - - // send group message to common channel with details on pending and approved reviewers - updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); + approvedReviewers.add(reviewerEmail); Boolean actionEnabled = true; - - if (checkRequiredApprovals(jitRequest)) { + if (authUtil.checkRequiredApprovals(jitRequest)) { // if required number of approvals are met, // 1. schedule JIT(just in time) DAGs - one for grant and another for grant, // 2. inform user on slack that request is approved, // 3. update the status in jit_approvals and jit_requests, - airflowClient.triggerJitDag(jitRequest, dagId, "runId-1", "grant"); - airflowClient.triggerJitDag(jitRequest, dagId, "runId-2", "revoke"); + String runId = String.join("-", jitRequest.getId().toString(), + jitRequest.getTeam().getName(), jitRequest.getEnvironment().toString(), + jitRequest.getRequestedFor().getEmail(), jitRequest.getResourceType(), + jitRequest.getResourceAction()); + airflowClient.triggerJitDag(jitRequest, dagId, runId+"grant", "grant"); + airflowClient.triggerJitDag(jitRequest, dagId, runId+"revoke", "revoke"); jitRequest.setStatus(JitRequestStatus.APPROVED); actionEnabled = false; } - updatePersonalMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers, actionEnabled); + // inform reviewer on slack that request is approved and remove action buttons + updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + + // send group message to common channel with details on pending and approved reviewers + jitRequest = updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, + rejectedReviewers); + jitRequest = updatePersonalMessageOnSlack(jitRequest, pendingReviewers, + approvedReviewers, rejectedReviewers, actionEnabled); jitRequestRepository.save(jitRequest); jitApprovalsRepository.save(jitApproval); @@ -220,20 +200,54 @@ public class JitServiceImpl implements JitService { } } + private Integer jitRejectedFlow( + String reviewerEmail, + JitApproval jitApproval, + JitRequest jitRequest, + List pendingReviewers, + List approvedReviewers, + List rejectedReviewers + ) { + try { + rejectedReviewers.add(reviewerEmail); + + jitApproval.setAction(JitRequestStatus.REJECTED); + jitRequest.setStatus(JitRequestStatus.REJECTED); + + updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + jitRequest = updatePersonalMessageOnSlack(jitRequest, pendingReviewers, + approvedReviewers, rejectedReviewers, false); + jitRequest = updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, + rejectedReviewers); + + jitApprovalsRepository.save(jitApproval); + jitRequestRepository.save(jitRequest); + + return 0; + } catch (Exception e) { + log.error("Failed to connect to airflow or failed to flush to DB", e.getCause()); + return -1; + } + } + private Integer jitCancelledFlow( String closerEmail, JitRequest jitRequest ) { try { jitRequest.setStatus(JitRequestStatus.CANCELLED); - List jitApprovals = jitApprovalsRepository.findAllReviewsByJitId(jitRequest.getId()).stream().map(JitApproval::getId).collect(Collectors.toList()); - for (Long approvalId : jitApprovals) { - JitApproval jitApproval = jitApprovalsRepository.findById(approvalId).get(); + List jitApprovals = jitApprovalsRepository.findAllReviewsByJitId( + jitRequest.getId()); + for (JitApproval jitApproval : jitApprovals) { + jitApproval.setReviewedAt(LocalDateTime.now()); jitApproval.setAction(JitRequestStatus.CANCELLED); jitApprovalsRepository.save(jitApproval); - updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, + false); } - updateGroupMessageOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); - updatePersonalMessageOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), false); + jitRequest = updateGroupMessageOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), + new ArrayList<>()); + jitRequest = updatePersonalMessageOnSlack(jitRequest, new ArrayList<>(), + new ArrayList<>(), new ArrayList<>(), false); jitRequestRepository.save(jitRequest); return 0; } catch (Exception e) { @@ -242,34 +256,6 @@ public class JitServiceImpl implements JitService { } } - private Integer jitRejectedFlow( - String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest - ) { - try { - jitApproval.setAction(JitRequestStatus.REJECTED); - jitRequest.setStatus(JitRequestStatus.REJECTED); - - List pendingReviewers = getReviewersByAction(userService, jitRequest.getId(), - JitRequestStatus.PENDING); - List approvedReviewers = getReviewersByAction(userService, jitRequest.getId(), - JitRequestStatus.APPROVED); - List rejectedReviewers = getReviewersByAction(userService, jitRequest.getId(), - JitRequestStatus.REJECTED); - - updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); - updatePersonalMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers, false); - updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); - - jitApprovalsRepository.save(jitApproval); - jitRequestRepository.save(jitRequest); - - return 0; - } catch (Exception e) { - log.error("Failed to connect to airflow or failed to flush to DB", e.getCause()); - return -1; - } - } - private JitRequest mapToJitRequest(JitRequestDTO jitRequestDTO) { return new JitRequest(userService.findUserByEmail(jitRequestDTO.getRequestedFor()), userService.findUserByEmail(jitRequestDTO.getRequestedBy()), @@ -279,104 +265,6 @@ public class JitServiceImpl implements JitService { JitRequestStatus.PENDING, jitRequestDTO.getGrantWindow(), jitRequestDTO.getGrantAt()); } - private SlackBotAttachment getReviewerMessage( - String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled - ) { - ArrayList blocks = new ArrayList<>(); - - SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, - String.format("Access request reviewed for user %s\n" + "\t*Vertical*\n" + "\t%s\n\n" - + "\t*Environment*\t\t\t\t\t*Resource*\n" + "\t%s\t\t\t\t\t\t\t\t %s\n\n" - + "\t*Grant At/On*\t\t\t\t\t*Grant Window(In hours)*\n" + "\t%s\t\t %s\n\n" - + "Request status: %s", userEmail, jitRequest.getVertical().toString(), - jitRequest.getEnvironment().toString(), jitRequest.getResourceType(), - jitRequest.getGrantAt().truncatedTo(ChronoUnit.MINUTES), - jitRequest.getGrantWindow(), jitApproval.getAction().toString())); - SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( - SlackMessageBlockType.SECTION, reviewRequestText, null); - blocks.add(reviewRequestSection); - - if (actionEnabled){ - SlackMessageText approveText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, - "Approve"); - SlackMessageElement approveButton = new SlackMessageElement(SlackElementType.BUTTON, - approveText, SlackElementStyle.PRIMARY, - String.join("-", jitRequest.getId().toString(), jitApproval.getReviewer().getEmail()), - "actionApprove"); - - SlackMessageText rejectText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, - "Reject"); - SlackMessageElement rejectButton = new SlackMessageElement(SlackElementType.BUTTON, - rejectText, SlackElementStyle.DANGER, - String.join("-", jitRequest.getId().toString(), jitApproval.getReviewer().getEmail()), - "actionReject"); - - ArrayList elements = new ArrayList<>(); - elements.add(approveButton); - elements.add(rejectButton); - - SlackBotMessageBlock reviewRequestAction = new SlackBotMessageBlock( - SlackMessageBlockType.ACTIONS, null, elements); - - blocks.add(reviewRequestAction); - } - - return new SlackBotAttachment("#f2c744", blocks); - } - - private SlackBotAttachment getPersonalMessage( - String userEmail, - JitRequest jitRequest, - Boolean actionEnabled, - List pendingReviewers, - List approvedReviewers, - List rejectedReviewers, - String requestStatus - ) { - SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, - String.format("Access request raised for user %s\n" + "\tPending Reviewers: %s\n" - + "\tApproved Reviewers: %s\n" + "\tRejected Reviewers: %s\n" - + "\tCurrent Status: %s\n", userEmail, pendingReviewers.toString(), - approvedReviewers.toString(), rejectedReviewers.toString(), requestStatus)); - - SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( - SlackMessageBlockType.SECTION, reviewRequestText, null); - - SlackMessageText rejectText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, - "Reject"); - SlackMessageElement closeButton = new SlackMessageElement(SlackElementType.BUTTON, - rejectText, SlackElementStyle.DANGER, jitRequest.getId().toString(), "actionClose"); - - ArrayList blocks = new ArrayList<>(); - blocks.add(reviewRequestSection); - - if (actionEnabled) { - ArrayList elements = new ArrayList<>(); - elements.add(closeButton); - SlackBotMessageBlock reviewRequestAction = new SlackBotMessageBlock( - SlackMessageBlockType.ACTIONS, null, elements); - blocks.add(reviewRequestAction); - } - - return new SlackBotAttachment("#f2c744", blocks); - } - - private SlackBotAttachment getGroupMessage(JitRequest jitRequest, - String email, List pendingReviewers, List approvedReviewers, List rejectedReviewers - ) { - SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, - String.format("Access request raised for user %s\n" + "\tPending Reviewers: %s\n" - + "\tApproved By: %s\n\tRejected By: %s\n\tCurrent status: %s", email, pendingReviewers.toString(), - approvedReviewers.toString(), rejectedReviewers.toString(), jitRequest.getStatus().toString())); - - SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( - SlackMessageBlockType.SECTION, reviewRequestText, null); - - ArrayList blocks = new ArrayList<>(); - blocks.add(reviewRequestSection); - return new SlackBotAttachment("#f2c744", blocks); - } - @Override public Boolean createJitRequest(JitRequestDTO jitRequestDTO) throws IOException { // validations here @@ -392,13 +280,7 @@ public class JitServiceImpl implements JitService { JitRequest jitRequest = mapToJitRequest(jitRequestDTO); // Determine the reviewers based on REQUEST - Role reviewerRole = new Role(String.join("_", jitRequestDTO.getTeam(), - jitRequestDTO.getEnvironment().toString().toLowerCase(), JITREVIEWER.toString())); - List reviewers = userService.getUsersWithRole(reviewerRole.getName()); - reviewerRole = new Role( - String.join("_", jitRequestDTO.getTeam(), "ALL", JITREVIEWER.toString())); - - reviewers.addAll(userService.getUsersWithRole(reviewerRole.getName())); + List reviewers = authUtil.getReviewers(jitRequestDTO); log.info("Requesting review from {}", reviewers); List jitApprovals = new ArrayList<>(); @@ -406,38 +288,52 @@ public class JitServiceImpl implements JitService { String messageTimestamp = ""; for (User reviewer : reviewers) { if (reviewer.getEmail().equals(jitRequest.getRequestedFor().getEmail())) { + // User cannot review his/her own request continue; } JitApproval jitApproval = new JitApproval(jitRequest, reviewer, JitRequestStatus.PENDING); jitApprovals.add(jitApproval); - // send review request to reviewers + // send review request/message to reviewers String reviewersEmail = reviewer.getEmail(); pendingReviewers.add(reviewersEmail); - - updateReviewerMessageOnSlack(reviewer, jitRequest, jitApproval, true); } + // send personal message to user with details on pending and approved reviewers - updatePersonalMessageOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), new ArrayList<>(), true); + JitRequest jitRequestWithId = jitRequestRepository.save(jitRequest); + jitRequest = updatePersonalMessageOnSlack(jitRequestWithId, pendingReviewers, + new ArrayList<>(), new ArrayList<>(), true); // send group message to common channel with details on pending and approved reviewers - updateGroupMessageOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), new ArrayList<>()); + jitRequest = updateGroupMessageOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), + new ArrayList<>()); + + List jitApprovalsWithId = jitApprovalsRepository.saveAll(jitApprovals); + JitRequest finalJitRequest = jitRequest; + jitApprovalsWithId.stream().forEach(jitApproval -> { + try { + updateReviewerMessageOnSlack(jitApproval.getReviewer(), + finalJitRequest, jitApproval, true); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); - jitApprovalsRepository.saveAll(jitApprovals); jitRequestRepository.save(jitRequest); - return true; } @Override public Integer approveJitRequest(String approver, Long requestId) throws IOException { - return processJitRequest(approver, requestId, this::jitApprovedFlow); + return processJitRequest(approver, requestId, JitRequestStatus.APPROVED, + this::jitApprovedFlow); } @Override public Integer rejectJitRequest(String rejecter, Long requestId) throws IOException { - return processJitRequest(rejecter, requestId, this::jitRejectedFlow); + return processJitRequest(rejecter, requestId, JitRequestStatus.REJECTED, + this::jitRejectedFlow); } // @Override @@ -464,10 +360,9 @@ public class JitServiceImpl implements JitService { if (jitRequests.isPresent()) { JitRequest jitRequest = jitRequests.get(); if (jitRequest.getRequestedFor().getEmail().equals(closer)) { - jitRequestRepository.updateRequestStatus(requestId); jitCancelledFlow(closer, jitRequest); } else { - log.error("User {} not allowed to reject request", closer); + log.error("User {} not allowed to close request", closer); return new JitResponseDTO(-1, null, null); } return new JitResponseDTO(requestId, jitRequests.get().getStatus(), null); @@ -478,7 +373,14 @@ public class JitServiceImpl implements JitService { @FunctionalInterface interface JitFlowFunction { - Integer apply(String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest) + Integer apply( + String reviewerEmail, + JitApproval jitApproval, + JitRequest jitRequest, + List pendingReviewers, + List approvedReviewers, + List rejectedReviewers + ) throws IOException; } } \ No newline at end of file diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java new file mode 100644 index 00000000..09c26bfc --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -0,0 +1,88 @@ +package com.navi.infra.portal.v2.jit.utils; + +import static com.navi.infra.portal.v2.role.Actor.JITREVIEWER; + +import com.navi.infra.portal.domain.user.User; +import com.navi.infra.portal.domain.user.Role; +import com.navi.infra.portal.service.user.UserService; +import com.navi.infra.portal.v2.jit.dto.JitRequestDTO; +import com.navi.infra.portal.v2.jit.entity.Environment; +import com.navi.infra.portal.v2.role.RoleService; +import com.navi.infra.portal.v2.jit.entity.JitRequest; +import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; +import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; +import java.util.List; +import java.util.stream.Collectors; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +@Slf4j +public class AuthUtil { + private final UserService userService; + private final RoleService roleService; + private final JitApprovalsRepository jitApprovalsRepository; + + @Value("${jit.number_of_prod_approvals}") + private Long prodJitApprovalsCount; + @Value("${jit.number_of_nonprod_approvals}") + private Long nonprodJitApprovalsCount; + + public boolean isAuthorized(String user, JitRequest jitRequest) { + List userRolesId = userService.listAllRolesOfUser(user); + List userRoles = roleService.listAllAuthorities(userRolesId); + + return userRoles.stream().filter( + role -> role.contains(JITREVIEWER.toString()) && role.contains( + jitRequest.getTeam().getName())).anyMatch( + role -> role.contains(jitRequest.getEnvironment().toString()) || role.contains("ALL")); + } + public List getReviewersByAction( + UserService userService, Long jitId, JitRequestStatus jitRequestStatus + ) { + return userService.findAllByIds( + jitApprovalsRepository.findReviewersByAction(jitId, jitRequestStatus.toString())) + .parallelStream().map(User::getEmail).collect(Collectors.toList()); + } + + public Boolean checkRequiredApprovals(JitRequest jitRequest) { + Environment env = jitRequest.getEnvironment(); + Long approvedRequests = jitApprovalsRepository.findApprovedRequestsCount( + jitRequest.getId()); + boolean approved = false; + switch(env) { + case PROD: + case CMD: + case DATA_PLATFORM_PROD: + approved = approvedRequests >= prodJitApprovalsCount; + break; + case NONPROD: + case DEV: + case QA: + case DATA_PLATFORM_NONPROD: + case UAT: + case PERF: + approved = approvedRequests >= nonprodJitApprovalsCount; + break; + default: + log.error("Invalid environment: {}", env); + } + return approved; + } + + public List getReviewers(JitRequestDTO jitRequestDTO) { + // Determine the reviewers based on REQUEST + Role reviewerRole = new Role(String.join("_", jitRequestDTO.getTeam(), + jitRequestDTO.getEnvironment().toString().toLowerCase(), JITREVIEWER.toString())); + List reviewers = userService.getUsersWithRole(reviewerRole.getName()); + reviewerRole = new Role( + String.join("_", jitRequestDTO.getTeam(), "ALL", JITREVIEWER.toString())); + reviewers.addAll(userService.getUsersWithRole(reviewerRole.getName())); + + return reviewers; + } +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java new file mode 100644 index 00000000..fed975a7 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -0,0 +1,123 @@ +package com.navi.infra.portal.v2.jit.utils; + +import com.navi.infra.portal.dto.slack.SlackMessageBlockType; +import com.navi.infra.portal.dto.slack.SlackMessageText; +import com.navi.infra.portal.dto.slack.SlackMessageTextType; +import com.navi.infra.portal.v2.jit.entity.JitApproval; +import com.navi.infra.portal.v2.jit.entity.JitRequest; +import com.navi.infra.portal.v2.slackbotclient.SlackBotAttachment; +import com.navi.infra.portal.v2.slackbotclient.SlackBotMessageBlock; +import com.navi.infra.portal.v2.slackbotclient.SlackElementStyle; +import com.navi.infra.portal.v2.slackbotclient.SlackElementType; +import com.navi.infra.portal.v2.slackbotclient.SlackMessageElement; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class SlackBotUtil { + public SlackBotAttachment getReviewerMessage( + String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled + ) { + ArrayList blocks = new ArrayList<>(); + + SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, + String.format("Access request reviewed for user %s\n" + "\t*Vertical*\n" + "\t%s\n\n" + + "\t*Environment*\t\t\t\t\t*Resource*\n" + "\t%s\t\t\t\t\t\t\t\t %s\n\n" + + "\t*Grant At/On*\t\t\t\t\t*Grant Window(In hours)*\n" + "\t%s\t\t %s\n\n" + + "Request status: %s", userEmail, jitRequest.getVertical().toString(), + jitRequest.getEnvironment().toString(), jitRequest.getResourceType(), + jitRequest.getGrantAt().truncatedTo(ChronoUnit.MINUTES), + jitRequest.getGrantWindow(), jitApproval.getAction().toString())); + SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( + SlackMessageBlockType.SECTION, reviewRequestText, null); + blocks.add(reviewRequestSection); + + if (actionEnabled) { + SlackMessageText approveText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, + "Approve"); + SlackMessageElement approveButton = new SlackMessageElement(SlackElementType.BUTTON, + approveText, SlackElementStyle.PRIMARY, + jitApproval.getId().toString(), + "actionApprove"); + + SlackMessageText rejectText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, + "Reject"); + SlackMessageElement rejectButton = new SlackMessageElement(SlackElementType.BUTTON, + rejectText, SlackElementStyle.DANGER, + jitApproval.getId().toString(), + "actionReject"); + + ArrayList elements = new ArrayList<>(); + elements.add(approveButton); + elements.add(rejectButton); + + SlackBotMessageBlock reviewRequestAction = new SlackBotMessageBlock( + SlackMessageBlockType.ACTIONS, null, elements); + + blocks.add(reviewRequestAction); + } + + return new SlackBotAttachment("#f2c744", blocks); + } + + public SlackBotAttachment getPersonalMessage( + String userEmail, + JitRequest jitRequest, + Boolean actionEnabled, + List pendingReviewers, + List approvedReviewers, + List rejectedReviewers, + String requestStatus + ) { + SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, + String.format("Access request raised for user %s\n" + "\tPending Reviewers: %s\n" + + "\tApproved Reviewers: %s\n" + "\tRejected Reviewers: %s\n" + + "\tCurrent Status: %s\n", userEmail, pendingReviewers.toString(), + approvedReviewers.toString(), rejectedReviewers.toString(), requestStatus)); + + SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( + SlackMessageBlockType.SECTION, reviewRequestText, null); + + SlackMessageText closeText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, + "Close"); + SlackMessageElement closeButton = new SlackMessageElement(SlackElementType.BUTTON, + closeText, SlackElementStyle.DANGER, jitRequest.getId().toString(), "actionClose"); + + ArrayList blocks = new ArrayList<>(); + blocks.add(reviewRequestSection); + + if (actionEnabled) { + ArrayList elements = new ArrayList<>(); + elements.add(closeButton); + SlackBotMessageBlock reviewRequestAction = new SlackBotMessageBlock( + SlackMessageBlockType.ACTIONS, null, elements); + blocks.add(reviewRequestAction); + } + + return new SlackBotAttachment("#f2c744", blocks); + } + + public SlackBotAttachment getGroupMessage( + JitRequest jitRequest, + String email, + List pendingReviewers, + List approvedReviewers, + List rejectedReviewers + ) { + SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, + String.format("Access request raised for user %s\n" + "\tPending Reviewers: %s\n" + + "\tApproved By: %s\n\tRejected By: %s\n\tCurrent status: %s", email, + pendingReviewers.toString(), + approvedReviewers.toString(), rejectedReviewers.toString(), + jitRequest.getStatus().toString())); + + SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( + SlackMessageBlockType.SECTION, reviewRequestText, null); + + ArrayList blocks = new ArrayList<>(); + blocks.add(reviewRequestSection); + return new SlackBotAttachment("#f2c744", blocks); + } +} diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/validateRequest.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/validateRequest.java deleted file mode 100644 index a9f63776..00000000 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/validateRequest.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.navi.infra.portal.v2.jit.utils; - -public class validateRequest { -} diff --git a/src/main/java/com/navi/infra/portal/v2/privilege/PrivilegeServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/privilege/PrivilegeServiceImpl.java index 61ef7d94..97b7fb0f 100644 --- a/src/main/java/com/navi/infra/portal/v2/privilege/PrivilegeServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/privilege/PrivilegeServiceImpl.java @@ -16,15 +16,11 @@ public class PrivilegeServiceImpl implements PrivilegeService { private final List environmentList; - private final List jitEnvironmentList; - public PrivilegeServiceImpl( PrivilegeRepository repository, - @Value("${environment.list}") List environmentList, - @Value("${jit.environment.list}") List jitEnvironmentList) { + @Value("${environment.list}") List environmentList) { this.repository = repository; this.environmentList = environmentList; - this.jitEnvironmentList = jitEnvironmentList; } @Override diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java index f2451655..48a08f43 100644 --- a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java @@ -1,27 +1,16 @@ package com.navi.infra.portal.v2.slackbotclient; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.JsonArray; import com.slack.api.methods.SlackApiException; -import com.slack.api.model.Attachment; import com.slack.api.model.User; import java.io.IOException; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; import org.springframework.stereotype.Component; import org.springframework.beans.factory.annotation.Value; -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; import com.slack.api.Slack; @@ -34,8 +23,6 @@ public class SlackBotClient { private static final String postMessage = "chat.postMessage"; @Value("${slackbot.token}") private String slackBotToken; - @Value("${slackbot.signing.secret}") - private String slackBotSigningSecret; public Map fetchAndProcessSlackUsers() throws IOException { Map userSlackIdMap = new HashMap<>(); @@ -63,17 +50,18 @@ public class SlackBotClient { return userSlackIdMap; } - public String postMessage(String channelId, SlackBotAttachment slackBotAttachment) throws IOException { + public String postMessage(String channelId, SlackBotAttachment slackBotAttachment) + throws IOException { var client = Slack.getInstance().methods(); // Slack client reference: https://api.slack.com/methods/chat.postMessage/code try { ObjectMapper objectMapper = new ObjectMapper(); String textJson = "[" + objectMapper.writeValueAsString(slackBotAttachment) + "]"; var result = client.chatPostMessage(r -> r - .token(slackBotToken) - .channel(channelId) - .text("Just In Time Access Manager") - .attachmentsAsString(textJson) + .token(slackBotToken) + .channel(channelId) + .text("Just In Time Access Manager") + .attachmentsAsString(textJson) ); return result.getTs(); } catch (IOException | SlackApiException e) { @@ -82,17 +70,18 @@ public class SlackBotClient { return ""; } - public String updateMessage(String channelId, SlackBotAttachment slackBotAttachment, String ts) throws IOException { + public String updateMessage(String channelId, SlackBotAttachment slackBotAttachment, String ts) + throws IOException { var client = Slack.getInstance().methods(); try { ObjectMapper objectMapper = new ObjectMapper(); String textJson = "[" + objectMapper.writeValueAsString(slackBotAttachment) + "]"; var result = client.chatUpdate(r -> r - .token(slackBotToken) - .channel(channelId) - .ts(ts) - .text("Just In Time Access Manager") - .attachmentsAsString(textJson) + .token(slackBotToken) + .channel(channelId) + .ts(ts) + .text("Just In Time Access Manager") + .attachmentsAsString(textJson) ); return result.getTs(); } catch (IOException | SlackApiException e) { diff --git a/src/main/resources/db/migration/V1.68__Add_just_in_time_requests_table.sql b/src/main/resources/db/migration/V1.68__Add_just_in_time_requests_table.sql index cc73058a..c40a4f2b 100644 --- a/src/main/resources/db/migration/V1.68__Add_just_in_time_requests_table.sql +++ b/src/main/resources/db/migration/V1.68__Add_just_in_time_requests_table.sql @@ -14,5 +14,5 @@ CREATE TABLE jit_requests ( grant_window BIGINT NOT NULL, grant_at timestamp without time zone, personal_slack_message_timestamp character varying(255), - group_slack_message_timestamp character varying(255), + group_slack_message_timestamp character varying(255) ); \ No newline at end of file diff --git a/src/main/resources/db/migration/V1.69__Add_just_in_time_approvals_table.sql b/src/main/resources/db/migration/V1.69__Add_just_in_time_approvals_table.sql index d303e3d6..1daa6d9a 100644 --- a/src/main/resources/db/migration/V1.69__Add_just_in_time_approvals_table.sql +++ b/src/main/resources/db/migration/V1.69__Add_just_in_time_approvals_table.sql @@ -6,5 +6,5 @@ CREATE TABLE jit_approvals ( reviewer_id BIGINT NOT NULL REFERENCES users(id), reviewed_at timestamp without time zone, action character varying(255) NOT NULL, - slack_message_timestamp character varying(255), + slack_message_timestamp character varying(255) ); \ No newline at end of file diff --git a/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java index ad222f13..237b9a78 100644 --- a/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java @@ -29,7 +29,7 @@ class RoleServiceImplTest { ); roleServiceImpl = new RoleServiceImpl( null, - new PrivilegeServiceImpl(null, environmentList, environmentList), + new PrivilegeServiceImpl(null, environmentList), environmentList, rolePrivilegesEnvMap); From 12a5aa30afd3a6bbc11bf182361ffecd3cdb0579 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 22 Mar 2024 17:15:37 +0530 Subject: [PATCH 009/108] INFRA-2219 | Harinder | Modularizing code, updating repository code, airflowclient after testing, slackbotclient INFRA-2219 | Harinder | Updating application.properties for tests --- src/main/resources/application.properties | 7 ++++++- src/test/resources/application.properties | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8fb7b0e1..600651cb 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -70,4 +70,9 @@ airflow.token=${AIRFLOW_AUTH_TOKEN} service-dump.dag.id=${SERVICE_DUMP_DAG_ID} service-dump.image.name=${SERVICE_DUMP_IMAGE_NAME:193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/openjdk:11.0.16-user4k} aws.profile=${AWS_PROFILE:default} -spring.mvc.async.request-timeout=1800000 \ No newline at end of file +spring.mvc.async.request-timeout=1800000 +jit.number_of_prod_approvals=2 +jit.number_of_nonprod_approvals=1 +slackbot.token=xoxb-6761910733-191044292705-1 +jit.dag.id=${JIT_DAG_ID} +jit.slack.common.channel.id=C06NDTBFA1G \ No newline at end of file diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index e829083e..bd3328e0 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -58,8 +58,13 @@ aws.profile=${AWS_PROFILE:default} kubernetes.security-group.id.fetch.fixed-backoff.interval=${SECURITY_GROUP_ID_FETCH_FIXED_BACKOFF_INTERVAL:2000} kubernetes.security-group.id.fetch.fixed-backoff.max-attempts=${SECURITY_GROUP_ID_FETCH_FIXED_BACKOFF_MAX_ATTEMPTS:5} extraResource.list=database,docdb,elasticCache,aws_access,dynamodb,s3_buckets,deployment - airflow.url=${AIRFLOW_URL:http://localhost:9090} +jit.airflow.url=${JIT_AIRFLOW_URL:http://localhost:9090} airflow.token=${AIRFLOW_AUTH_TOKEN:something} service-dump.dag.id=${SERVICE_DUMP_DAG_ID:kubectl_get_pod} +jit.dag.id=${JIT_DAG_ID:jit_dag} service-dump.image.name=${SERVICE_DUMP_IMAGE_NAME:193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/openjdk:11.0.16-user4k} +jit.number_of_prod_approvals=2 +jit.number_of_nonprod_approvals=1 +jit.slack.common.channel.id=C06NDTBFA1G +slackbot.token=xoxb-676123123123-123123123123-123123123123-123123123123 \ No newline at end of file From bb2a1c274bceb18b0e045ec5229d4458920deb1f Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 22 Mar 2024 18:02:18 +0530 Subject: [PATCH 010/108] INFRA-2219 | Harinder | Updating db migration versioning post merge --- ...uests_table.sql => V1.69__Add_just_in_time_requests_table.sql} | 0 ...vals_table.sql => V1.70__Add_just_in_time_approvals_table.sql} | 0 ...t_roles_privileges.sql => V1.71__Add_jit_roles_privileges.sql} | 0 ..._user_id.sql => V1.72__Alter_user_table_add_slack_user_id.sql} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{V1.68__Add_just_in_time_requests_table.sql => V1.69__Add_just_in_time_requests_table.sql} (100%) rename src/main/resources/db/migration/{V1.69__Add_just_in_time_approvals_table.sql => V1.70__Add_just_in_time_approvals_table.sql} (100%) rename src/main/resources/db/migration/{V1.70__Add_jit_roles_privileges.sql => V1.71__Add_jit_roles_privileges.sql} (100%) rename src/main/resources/db/migration/{V1.71__Alter_user_table_add_slack_user_id.sql => V1.72__Alter_user_table_add_slack_user_id.sql} (100%) diff --git a/src/main/resources/db/migration/V1.68__Add_just_in_time_requests_table.sql b/src/main/resources/db/migration/V1.69__Add_just_in_time_requests_table.sql similarity index 100% rename from src/main/resources/db/migration/V1.68__Add_just_in_time_requests_table.sql rename to src/main/resources/db/migration/V1.69__Add_just_in_time_requests_table.sql diff --git a/src/main/resources/db/migration/V1.69__Add_just_in_time_approvals_table.sql b/src/main/resources/db/migration/V1.70__Add_just_in_time_approvals_table.sql similarity index 100% rename from src/main/resources/db/migration/V1.69__Add_just_in_time_approvals_table.sql rename to src/main/resources/db/migration/V1.70__Add_just_in_time_approvals_table.sql diff --git a/src/main/resources/db/migration/V1.70__Add_jit_roles_privileges.sql b/src/main/resources/db/migration/V1.71__Add_jit_roles_privileges.sql similarity index 100% rename from src/main/resources/db/migration/V1.70__Add_jit_roles_privileges.sql rename to src/main/resources/db/migration/V1.71__Add_jit_roles_privileges.sql diff --git a/src/main/resources/db/migration/V1.71__Alter_user_table_add_slack_user_id.sql b/src/main/resources/db/migration/V1.72__Alter_user_table_add_slack_user_id.sql similarity index 100% rename from src/main/resources/db/migration/V1.71__Alter_user_table_add_slack_user_id.sql rename to src/main/resources/db/migration/V1.72__Alter_user_table_add_slack_user_id.sql From 6297dc6c22b2880f9f10595093f5d0fea820cca0 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 22 Mar 2024 18:22:40 +0530 Subject: [PATCH 011/108] INFRA-2219 | Harinder | Updating coding in accordance with checkstyle --- .../portal/repository/UserRepository.java | 10 ++- .../portal/service/user/UserService.java | 6 +- .../v2/client/airflow/AirflowClient.java | 19 ++-- .../v2/jit/controller/JitController.java | 70 ++++++++------- ...{JitRequestDTO.java => JitRequestDto.java} | 5 +- ...itResponseDTO.java => JitResponseDto.java} | 9 +- .../dto/{JitUserDTO.java => JitUserDto.java} | 4 +- .../portal/v2/jit/entity/Environment.java | 4 +- .../portal/v2/jit/entity/JitApproval.java | 6 +- .../infra/portal/v2/jit/entity/Vertical.java | 4 +- .../repository/JitApprovalsRepository.java | 19 ++-- .../jit/repository/JitRequestsRepository.java | 6 +- .../portal/v2/jit/service/JitService.java | 11 +-- .../portal/v2/jit/service/JitServiceImpl.java | 90 +++++++++---------- .../infra/portal/v2/jit/utils/AuthUtil.java | 28 +++--- .../portal/v2/jit/utils/SlackBotUtil.java | 1 + .../infra/portal/v2/role/RoleRepository.java | 3 +- .../infra/portal/v2/role/RoleServiceImpl.java | 28 +++--- .../v2/slackbotclient/SlackBotClient.java | 4 +- .../slackbotclient/SlackBotMessageBlock.java | 11 ++- .../slackbotclient/SlackMessageElement.java | 21 +++-- .../portal/v2/role/RoleServiceImplTest.java | 9 +- 22 files changed, 211 insertions(+), 157 deletions(-) rename src/main/java/com/navi/infra/portal/v2/jit/dto/{JitRequestDTO.java => JitRequestDto.java} (89%) rename src/main/java/com/navi/infra/portal/v2/jit/dto/{JitResponseDTO.java => JitResponseDto.java} (78%) rename src/main/java/com/navi/infra/portal/v2/jit/dto/{JitUserDTO.java => JitUserDto.java} (80%) diff --git a/src/main/java/com/navi/infra/portal/repository/UserRepository.java b/src/main/java/com/navi/infra/portal/repository/UserRepository.java index 7e352f6a..e65ad07a 100644 --- a/src/main/java/com/navi/infra/portal/repository/UserRepository.java +++ b/src/main/java/com/navi/infra/portal/repository/UserRepository.java @@ -9,6 +9,7 @@ import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository { + @Query("SELECT u FROM User u WHERE lower(u.email) = :email") Optional findByEmail(String email); @@ -21,16 +22,19 @@ public interface UserRepository extends JpaRepository { @Query("SELECT u FROM User u WHERE lower(u.email) in (:emailList)") List> findAllByEmail(List emailList); - @Query(value = "SELECT ur.user_id FROM users_roles ur WHERE ur.role_id = :roleId", nativeQuery = true) + @Query(value = "SELECT ur.user_id FROM users_roles ur WHERE ur.role_id = :roleId", + nativeQuery = true) List findUserIdsByRoleIds(Long roleId); - @Query(value = "SELECT ur.role_id FROM users_roles ur WHERE ur.user_id = :userId)", nativeQuery = true) + @Query(value = "SELECT ur.role_id FROM users_roles ur WHERE ur.user_id = :userId)", + nativeQuery = true) List findAllRolesOfUser(Long userId); @Query(value = "SELECT u FROM users u WHERE u.id IN = :roleId)", nativeQuery = true) User findUsersByRoleName(Long roleId); - @Query(value = "SELECT u.slack_id FROM users u WHERE lower(u.email) = :email", nativeQuery = true) + @Query(value = "SELECT u.slack_id FROM users u WHERE lower(u.email) = :email", + nativeQuery = true) Optional findSlackId(String email); } diff --git a/src/main/java/com/navi/infra/portal/service/user/UserService.java b/src/main/java/com/navi/infra/portal/service/user/UserService.java index 14035a5c..1b868f0c 100644 --- a/src/main/java/com/navi/infra/portal/service/user/UserService.java +++ b/src/main/java/com/navi/infra/portal/service/user/UserService.java @@ -27,14 +27,12 @@ import com.navi.infra.portal.v2.role.RoleService; import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; import com.navi.infra.portal.v2.team.TeamService; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; import java.util.stream.Stream; import javassist.NotFoundException; import lombok.extern.slf4j.Slf4j; @@ -333,11 +331,11 @@ public class UserService { public String getSlackId(String email) throws IOException { Optional slackId = userRepository.findSlackId(email); - if (!slackId.isPresent()){ + if (!slackId.isPresent()) { var users = userRepository.findAll(); Map emailSlackIdMapping = slackBotClient.fetchAndProcessSlackUsers(); users.forEach(user -> { - if (user.getSlackId() == null || user.getSlackId().isEmpty()){ + if (user.getSlackId() == null || user.getSlackId().isEmpty()) { user.setSlackId(emailSlackIdMapping.get(user.getEmail())); } }); diff --git a/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java b/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java index bc91b586..559edcaf 100644 --- a/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java +++ b/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java @@ -7,12 +7,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.v2.dump.DumpTriggerRequest; import com.navi.infra.portal.v2.jit.entity.JitRequest; import java.net.URI; -import java.time.ZoneId; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.time.LocalDateTime; -import java.time.ZonedDateTime; import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; @@ -90,11 +88,18 @@ public class AirflowClient { } } - public AirflowApiResponse triggerJitDag(JitRequest jitRequest, String dagId, String runId, String action) { -// Date execution_date = action.equals("grant")? jitRequest.getGrantAt() : Date.from(jitRequest.getGrantAt().toInstant().plusSeconds(60*jitRequest.getGrantWindow())); - LocalDateTime executionDate = action.equals("grant")? jitRequest.getGrantAt() : jitRequest.getGrantAt().plusHours(jitRequest.getGrantWindow()); - var payloadMap = Map.of( //"dag_run_id", runId, - "execution_date", String.join("+",executionDate.toString(),"05:30"), + public AirflowApiResponse triggerJitDag( + JitRequest jitRequest, + String dagId, + String runId, + String action + ) { + LocalDateTime executionDate = action.equals("grant") ? jitRequest.getGrantAt() + : jitRequest.getGrantAt().plusHours(jitRequest.getGrantWindow()); + String apacheTimeFormat = String.join("+", + executionDate.toString(), "05:30"); + var payloadMap = Map.of("dag_run_id", runId, + "execution_date", apacheTimeFormat, "conf", Map.of( "vertical", jitRequest.getVertical().toString(), "team", jitRequest.getTeam().getName(), diff --git a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java index 05ee2333..502a52ab 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java @@ -1,25 +1,22 @@ package com.navi.infra.portal.v2.jit.controller; -import com.navi.infra.portal.v2.jit.dto.JitResponseDTO; -import com.navi.infra.portal.v2.jit.dto.JitUserDTO; -import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; +import com.navi.infra.portal.v2.jit.dto.JitRequestDto; +import com.navi.infra.portal.v2.jit.dto.JitResponseDto; +import com.navi.infra.portal.v2.jit.dto.JitUserDto; +import com.navi.infra.portal.v2.jit.service.JitService; import java.io.IOException; -import java.util.List; import javax.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Controller; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; - -import com.navi.infra.portal.v2.jit.dto.JitRequestDTO; -import com.navi.infra.portal.v2.jit.service.JitService; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; @Controller @RestController @@ -32,7 +29,8 @@ public class JitController { private final JitService jitService; @PostMapping - public ResponseEntity createJitRequest(@Valid @RequestBody JitRequestDTO jitRequestDto) { + public ResponseEntity createJitRequest( + @Valid @RequestBody JitRequestDto jitRequestDto) { try { return jitService.createJitRequest(jitRequestDto) ? ResponseEntity.status(HttpStatus.CREATED).build() @@ -44,7 +42,10 @@ public class JitController { } @PostMapping("/approve/{reviewId}") - public ResponseEntity approveJitRequest(@RequestBody JitUserDTO approver, @PathVariable Long reviewId ) { + public ResponseEntity approveJitRequest( + @RequestBody JitUserDto approver, + @PathVariable Long reviewId + ) { try { return jitService.approveJitRequest(approver.getUser(), reviewId) == -1 ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() @@ -56,7 +57,10 @@ public class JitController { } @PostMapping("/reject/{reviewId}") - public ResponseEntity rejectJitRequest(@RequestBody JitUserDTO rejecter, @PathVariable Long reviewId) { + public ResponseEntity rejectJitRequest( + @RequestBody JitUserDto rejecter, + @PathVariable Long reviewId + ) { try { return jitService.rejectJitRequest(rejecter.getUser(), reviewId) == -1 ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() @@ -67,29 +71,35 @@ public class JitController { } } -// @PostMapping("/status/{id}") -// public ResponseEntity getJitRequestStatus(@RequestBody JitUserDTO checker, @PathVariable Long id) { -// try { -// JitResponseDTO jitResponse = jitService.getJitRequestStatus(checker.getUser(), id); -// return jitResponse.getId() == -1 -// ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() -// : ResponseEntity.ok(jitResponse); -// } catch (Exception ex) { -// log.error("Exception: ", ex.getMessage()); -// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); -// } -// } - - @PostMapping("/close/{id}") - public ResponseEntity closeJitRequest(@RequestBody JitUserDTO closer, @PathVariable Long id) { + /* + @PostMapping("/status/{id}") + public ResponseEntity getJitRequestStatus(@RequestBody JitUserDTO checker, + @PathVariable Long id) { try { - JitResponseDTO jitResponse = jitService.closeRequest(closer.getUser(), id); + JitResponseDTO jitResponse = jitService.getJitRequestStatus(checker.getUser(), id); return jitResponse.getId() == -1 ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() - : ResponseEntity.status(HttpStatus.OK).build(); + : ResponseEntity.ok(jitResponse); } catch (Exception ex) { log.error("Exception: ", ex.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } + */ + + @PostMapping("/close/{id}") + public ResponseEntity closeJitRequest( + @RequestBody JitUserDto closer, + @PathVariable Long id + ) { + try { + JitResponseDto jitResponse = jitService.closeRequest(closer.getUser(), id); + return jitResponse.getId() == -1 + ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() + : ResponseEntity.status(HttpStatus.OK).build(); + } catch (Exception ex) { + log.error("Exception: ", ex.getMessage()); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); + } + } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDTO.java b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java similarity index 89% rename from src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDTO.java rename to src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java index df4e45f8..2d55246a 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDTO.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java @@ -3,9 +3,7 @@ package com.navi.infra.portal.v2.jit.dto; import com.navi.infra.portal.v2.jit.entity.Environment; import com.navi.infra.portal.v2.jit.entity.Vertical; import java.time.LocalDateTime; -import java.util.Date; import javax.validation.constraints.Email; -import javax.validation.constraints.NotBlank; import javax.validation.constraints.Positive; import lombok.AllArgsConstructor; import lombok.Getter; @@ -17,7 +15,8 @@ import lombok.Setter; //@Builder @NoArgsConstructor @AllArgsConstructor -public class JitRequestDTO { +public class JitRequestDto { + @Email private String requestedFor; diff --git a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitResponseDTO.java b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitResponseDto.java similarity index 78% rename from src/main/java/com/navi/infra/portal/v2/jit/dto/JitResponseDTO.java rename to src/main/java/com/navi/infra/portal/v2/jit/dto/JitResponseDto.java index d9de72d5..622a41c3 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitResponseDTO.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitResponseDto.java @@ -12,14 +12,19 @@ import lombok.Setter; @Setter @NoArgsConstructor @AllArgsConstructor -public class JitResponseDTO { +public class JitResponseDto { + private Long id; private JitRequestStatus jitRequestStatus; private List pendingReviews; - public JitResponseDTO(long id, JitRequestStatus jitRequestStatus, List pendingReviews) { + public JitResponseDto( + long id, + JitRequestStatus jitRequestStatus, + List pendingReviews + ) { this.id = id; this.jitRequestStatus = jitRequestStatus; this.pendingReviews = pendingReviews; diff --git a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitUserDTO.java b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitUserDto.java similarity index 80% rename from src/main/java/com/navi/infra/portal/v2/jit/dto/JitUserDTO.java rename to src/main/java/com/navi/infra/portal/v2/jit/dto/JitUserDto.java index 51ff16ff..701d8631 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitUserDTO.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitUserDto.java @@ -1,7 +1,6 @@ package com.navi.infra.portal.v2.jit.dto; import javax.validation.constraints.Email; -import javax.validation.constraints.Positive; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -11,7 +10,8 @@ import lombok.Setter; @Setter @NoArgsConstructor @AllArgsConstructor -public class JitUserDTO { +public class JitUserDto { + @Email private String user; } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java index 09d43510..55bc9dc3 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java @@ -13,5 +13,7 @@ public enum Environment { public final String type; - Environment(String type) {this.type = type;} + Environment(String type) { + this.type = type; + } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java index 391b45e1..03d5353d 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java @@ -5,14 +5,13 @@ import static lombok.AccessLevel.PACKAGE; import com.navi.infra.portal.domain.BaseEntity; import com.navi.infra.portal.domain.user.User; import java.time.LocalDateTime; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; -import javax.persistence.Id; -import javax.persistence.Column; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; - +import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @@ -28,6 +27,7 @@ import lombok.Setter; @Setter @Table(name = "jit_approvals") public class JitApproval extends BaseEntity { + private static final long serialVersionUID = -1852998120471377502L; @Id diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java index 9924cacf..aa4dba41 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java @@ -9,5 +9,7 @@ public enum Vertical { public final String type; - Vertical(String type) {this.type = type;} + Vertical(String type) { + this.type = type; + } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java index 2912a758..de92422b 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java @@ -8,15 +8,20 @@ import org.springframework.stereotype.Repository; @Repository public interface JitApprovalsRepository extends JpaRepository { - @Query(value = "SELECT ja.reviewer_id FROM jit_approvals ja WHERE ja.id = :id", nativeQuery = true) + + @Query(value = "SELECT ja.reviewer_id FROM jit_approvals ja WHERE ja.id = :id", + nativeQuery = true) String findReviewerId(Long id); - @Query(value = "SELECT ja.* FROM jit_approvals ja WHERE ja.jit_id = :jit_id", nativeQuery = true) - List findAllReviewsByJitId(Long jit_id); + @Query(value = "SELECT ja.* FROM jit_approvals ja WHERE ja.jit_id = :jitId", + nativeQuery = true) + List findAllReviewsByJitId(Long jitId); - @Query(value="SELECT COUNT(ja.reviewer_id) FROM jit_approvals ja WHERE ja.jit_id = :jit_id", nativeQuery = true) - Long findApprovedRequestsCount(Long jit_id); + @Query(value = "SELECT COUNT(ja.reviewer_id) FROM jit_approvals ja WHERE ja.jit_id = :jitId", + nativeQuery = true) + Long findApprovedRequestsCount(Long jitId); - @Query(value="SELECT ja.reviewer_id FROM jit_approvals ja WHERE ja.jit_id = :jit_id and ja.action = :action", nativeQuery = true) - List findReviewersByAction(Long jit_id, String action); + @Query(value = "SELECT ja.reviewer_id FROM jit_approvals ja " + + "WHERE ja.jit_id = :jitId and ja.action = :action", nativeQuery = true) + List findReviewersByAction(Long jitId, String action); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java index b4c6fe1d..44c9c3c2 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java @@ -8,7 +8,9 @@ import org.springframework.stereotype.Repository; @Repository public interface JitRequestsRepository extends JpaRepository { + @Modifying - @Query(value = "UPDATE jit_requests SET status = :action WHERE id = :jit_id", nativeQuery = true) - void updateRequestStatus(Long jit_id, String action); + @Query(value = "UPDATE jit_requests SET status = :action WHERE id = :jitId", + nativeQuery = true) + void updateRequestStatus(Long jitId, String action); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java index 954980f0..809b6a58 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java @@ -1,17 +1,18 @@ package com.navi.infra.portal.v2.jit.service; -import com.navi.infra.portal.v2.jit.dto.JitRequestDTO; -import com.navi.infra.portal.v2.jit.dto.JitResponseDTO; +import com.navi.infra.portal.v2.jit.dto.JitRequestDto; +import com.navi.infra.portal.v2.jit.dto.JitResponseDto; import java.io.IOException; public interface JitService { - Boolean createJitRequest (JitRequestDTO jitRequestDTO) throws IOException; + + Boolean createJitRequest(JitRequestDto jitRequestDto) throws IOException; Integer approveJitRequest(String approver, Long requestId) throws IOException; Integer rejectJitRequest(String rejecter, Long requestId) throws IOException; -// JitResponseDTO getJitRequestStatus(String checker, Long requestId); + // JitResponseDTO getJitRequestStatus(String checker, Long requestId); - JitResponseDTO closeRequest(String closer, Long requestId); + JitResponseDto closeRequest(String closer, Long requestId); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 864980db..9516f76d 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -1,14 +1,10 @@ package com.navi.infra.portal.v2.jit.service; -import static com.navi.infra.portal.v2.role.Actor.JITREVIEWER; - -import com.navi.infra.portal.domain.user.Role; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; import com.navi.infra.portal.v2.client.airflow.AirflowClient; -import com.navi.infra.portal.v2.jit.dto.JitRequestDTO; -import com.navi.infra.portal.v2.jit.dto.JitResponseDTO; -import com.navi.infra.portal.v2.jit.entity.Environment; +import com.navi.infra.portal.v2.jit.dto.JitRequestDto; +import com.navi.infra.portal.v2.jit.dto.JitResponseDto; import com.navi.infra.portal.v2.jit.entity.JitApproval; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; @@ -26,8 +22,6 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; -import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -113,10 +107,10 @@ public class JitServiceImpl implements JitService { JitRequestStatus jitRequestStatus, JitFlowFunction flowFunction ) throws IOException { - Optional jA = jitApprovalsRepository.findById(requestId); + Optional optionalJitApproval = jitApprovalsRepository.findById(requestId); - if (jA.isPresent()) { - JitApproval jitApproval = jA.get(); + if (optionalJitApproval.isPresent()) { + JitApproval jitApproval = optionalJitApproval.get(); JitRequest jitRequest = jitApproval.getJitRequest(); if (jitApproval.getReviewedAt() != null || !jitRequest.getStatus() .equals(JitRequestStatus.PENDING)) { @@ -175,8 +169,8 @@ public class JitServiceImpl implements JitService { jitRequest.getTeam().getName(), jitRequest.getEnvironment().toString(), jitRequest.getRequestedFor().getEmail(), jitRequest.getResourceType(), jitRequest.getResourceAction()); - airflowClient.triggerJitDag(jitRequest, dagId, runId+"grant", "grant"); - airflowClient.triggerJitDag(jitRequest, dagId, runId+"revoke", "revoke"); + airflowClient.triggerJitDag(jitRequest, dagId, runId + "grant", "grant"); + airflowClient.triggerJitDag(jitRequest, dagId, runId + "revoke", "revoke"); jitRequest.setStatus(JitRequestStatus.APPROVED); @@ -256,31 +250,31 @@ public class JitServiceImpl implements JitService { } } - private JitRequest mapToJitRequest(JitRequestDTO jitRequestDTO) { - return new JitRequest(userService.findUserByEmail(jitRequestDTO.getRequestedFor()), - userService.findUserByEmail(jitRequestDTO.getRequestedBy()), - jitRequestDTO.getVertical(), teamService.findByName(jitRequestDTO.getTeam()), - jitRequestDTO.getEnvironment(), jitRequestDTO.getResourceType(), - jitRequestDTO.getResourceId(), jitRequestDTO.getResourceAction(), - JitRequestStatus.PENDING, jitRequestDTO.getGrantWindow(), jitRequestDTO.getGrantAt()); + private JitRequest mapToJitRequest(JitRequestDto jitRequestDto) { + return new JitRequest(userService.findUserByEmail(jitRequestDto.getRequestedFor()), + userService.findUserByEmail(jitRequestDto.getRequestedBy()), + jitRequestDto.getVertical(), teamService.findByName(jitRequestDto.getTeam()), + jitRequestDto.getEnvironment(), jitRequestDto.getResourceType(), + jitRequestDto.getResourceId(), jitRequestDto.getResourceAction(), + JitRequestStatus.PENDING, jitRequestDto.getGrantWindow(), jitRequestDto.getGrantAt()); } @Override - public Boolean createJitRequest(JitRequestDTO jitRequestDTO) throws IOException { + public Boolean createJitRequest(JitRequestDto jitRequestDto) throws IOException { // validations here - if (jitRequestDTO.getGrantAt() == null) { - jitRequestDTO.setGrantAt(LocalDateTime.now()); - } else if (jitRequestDTO.getGrantAt().isBefore(LocalDateTime.now())) { - log.error("Invalid time: {} is before now {}", jitRequestDTO.getGrantAt(), + if (jitRequestDto.getGrantAt() == null) { + jitRequestDto.setGrantAt(LocalDateTime.now()); + } else if (jitRequestDto.getGrantAt().isBefore(LocalDateTime.now())) { + log.error("Invalid time: {} is before now {}", jitRequestDto.getGrantAt(), LocalDateTime.now()); return false; } // Map request DTO to JitRequest Entity and save in DB - JitRequest jitRequest = mapToJitRequest(jitRequestDTO); + JitRequest jitRequest = mapToJitRequest(jitRequestDto); // Determine the reviewers based on REQUEST - List reviewers = authUtil.getReviewers(jitRequestDTO); + List reviewers = authUtil.getReviewers(jitRequestDto); log.info("Requesting review from {}", reviewers); List jitApprovals = new ArrayList<>(); @@ -336,26 +330,28 @@ public class JitServiceImpl implements JitService { this::jitRejectedFlow); } -// @Override -// public JitResponseDTO getJitRequestStatus(String checker, Long requestId) { -// // verify if checker does have to permission to read JIT requests, -// // if so then inform about pending reviews -// Optional jitRequests = jitRequestRepository.findById(requestId); -// if (jitRequests.isPresent()) { -// JitRequest jR = jitRequests.get(); -// if (jR.getRequestedFor().getEmail().equals(checker)) { -// // use slackClient to update original message as well -// return new JitResponseDTO(jR.getId(), jR.getStatus(), new ArrayList<>()); -// } else { -// log.error("User {} not allowed to check request status", checker); -// return new JitResponseDTO(-1, null, null); -// } -// } -// return new JitResponseDTO(-1, null, null); -// } + /* + @Override + public JitResponseDTO getJitRequestStatus(String checker, Long requestId) { + // verify if checker does have to permission to read JIT requests, + // if so then inform about pending reviews + Optional jitRequests = jitRequestRepository.findById(requestId); + if (jitRequests.isPresent()) { + JitRequest jR = jitRequests.get(); + if (jR.getRequestedFor().getEmail().equals(checker)) { + // use slackClient to update original message as well + return new JitResponseDTO(jR.getId(), jR.getStatus(), new ArrayList<>()); + } else { + log.error("User {} not allowed to check request status", checker); + return new JitResponseDTO(-1, null, null); + } + } + return new JitResponseDTO(-1, null, null); + } + */ @Override - public JitResponseDTO closeRequest(String closer, Long requestId) { + public JitResponseDto closeRequest(String closer, Long requestId) { Optional jitRequests = jitRequestRepository.findById(requestId); if (jitRequests.isPresent()) { JitRequest jitRequest = jitRequests.get(); @@ -363,9 +359,9 @@ public class JitServiceImpl implements JitService { jitCancelledFlow(closer, jitRequest); } else { log.error("User {} not allowed to close request", closer); - return new JitResponseDTO(-1, null, null); + return new JitResponseDto(-1, null, null); } - return new JitResponseDTO(requestId, jitRequests.get().getStatus(), null); + return new JitResponseDto(requestId, jitRequests.get().getStatus(), null); } return null; } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 09c26bfc..2c2b090b 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -2,18 +2,17 @@ package com.navi.infra.portal.v2.jit.utils; import static com.navi.infra.portal.v2.role.Actor.JITREVIEWER; -import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.domain.user.Role; +import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; -import com.navi.infra.portal.v2.jit.dto.JitRequestDTO; +import com.navi.infra.portal.v2.jit.dto.JitRequestDto; import com.navi.infra.portal.v2.jit.entity.Environment; -import com.navi.infra.portal.v2.role.RoleService; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; +import com.navi.infra.portal.v2.role.RoleService; import java.util.List; import java.util.stream.Collectors; -import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -23,6 +22,7 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor @Slf4j public class AuthUtil { + private final UserService userService; private final RoleService roleService; private final JitApprovalsRepository jitApprovalsRepository; @@ -36,11 +36,13 @@ public class AuthUtil { List userRolesId = userService.listAllRolesOfUser(user); List userRoles = roleService.listAllAuthorities(userRolesId); - return userRoles.stream().filter( - role -> role.contains(JITREVIEWER.toString()) && role.contains( - jitRequest.getTeam().getName())).anyMatch( - role -> role.contains(jitRequest.getEnvironment().toString()) || role.contains("ALL")); + return userRoles.stream() + .filter(role -> role.contains(JITREVIEWER.toString()) + && role.contains(jitRequest.getTeam().getName())) + .anyMatch(role -> role.contains(jitRequest.getEnvironment().toString()) + || role.contains("ALL")); } + public List getReviewersByAction( UserService userService, Long jitId, JitRequestStatus jitRequestStatus ) { @@ -54,7 +56,7 @@ public class AuthUtil { Long approvedRequests = jitApprovalsRepository.findApprovedRequestsCount( jitRequest.getId()); boolean approved = false; - switch(env) { + switch (env) { case PROD: case CMD: case DATA_PLATFORM_PROD: @@ -74,13 +76,13 @@ public class AuthUtil { return approved; } - public List getReviewers(JitRequestDTO jitRequestDTO) { + public List getReviewers(JitRequestDto jitRequestDto) { // Determine the reviewers based on REQUEST - Role reviewerRole = new Role(String.join("_", jitRequestDTO.getTeam(), - jitRequestDTO.getEnvironment().toString().toLowerCase(), JITREVIEWER.toString())); + Role reviewerRole = new Role(String.join("_", jitRequestDto.getTeam(), + jitRequestDto.getEnvironment().toString().toLowerCase(), JITREVIEWER.toString())); List reviewers = userService.getUsersWithRole(reviewerRole.getName()); reviewerRole = new Role( - String.join("_", jitRequestDTO.getTeam(), "ALL", JITREVIEWER.toString())); + String.join("_", jitRequestDto.getTeam(), "ALL", JITREVIEWER.toString())); reviewers.addAll(userService.getUsersWithRole(reviewerRole.getName())); return reviewers; diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index fed975a7..5d1a1ba8 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -17,6 +17,7 @@ import org.springframework.stereotype.Component; @Component public class SlackBotUtil { + public SlackBotAttachment getReviewerMessage( String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled ) { diff --git a/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java b/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java index dc7563e9..97e7780f 100644 --- a/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java @@ -16,6 +16,7 @@ interface RoleRepository extends JpaRepository { List findByNameIn(List name); - @Query(value = "SELECT rp.privilege_id FROM roles_privileges rp WHERE rp.role_id = :roleId)", nativeQuery = true) + @Query(value = "SELECT rp.privilege_id FROM roles_privileges rp WHERE rp.role_id = :roleId)", + nativeQuery = true) List findAllPrivilegessOfRole(Long roleId); } diff --git a/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java index f3b1dfdc..aaf9a02f 100644 --- a/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java @@ -81,11 +81,13 @@ class RoleServiceImpl implements RoleService { return repository.findIdByName(role); } - public List listAllPrivilegesOfRole(Long roleId){ + public List listAllPrivilegesOfRole(Long roleId) { return repository.findAllPrivilegessOfRole(roleId); } - public List listAllAuthorities(List privilegeIds) { return null; } + public List listAllAuthorities(List privilegeIds) { + return null; + } @Override public List saveAll(List roles) { @@ -161,11 +163,16 @@ class RoleServiceImpl implements RoleService { private Map> mapWithPrivileges(String teamName, String env) { return Map.of( - generateName(teamName, env, VIEWER), viewerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), - generateName(teamName, env, MAINTAINER), maintainerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), - generateName(teamName, env, MANAGER), managerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), - generateName(teamName, env, JITREADER), jitViewerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), - generateName(teamName, env, JITREVIEWER), jitReviewerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)) + generateName(teamName, env, VIEWER), + viewerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), + generateName(teamName, env, MAINTAINER), + maintainerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), + generateName(teamName, env, MANAGER), + managerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), + generateName(teamName, env, JITREADER), + jitViewerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)), + generateName(teamName, env, JITREVIEWER), + jitReviewerPrivileges(teamName, rolesPrivilegesEnvironmentMap.get(env)) ); } @@ -207,10 +214,9 @@ class RoleServiceImpl implements RoleService { private List jitReviewerPrivileges(String teamName, String env) { final var privileges = new ArrayList<>(jitViewerPrivileges(teamName, env)); - privileges.addAll( - List.of( - privilegeService.generateName(JIT, teamName, env, ALL, JIT_REVIEWERS) - )); + privileges.add( + privilegeService.generateName(JIT, teamName, env, ALL, JIT_REVIEWERS) + ); return unmodifiableList(privileges); } diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java index 48a08f43..b4993eda 100644 --- a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java @@ -1,6 +1,7 @@ package com.navi.infra.portal.v2.slackbotclient; import com.fasterxml.jackson.databind.ObjectMapper; +import com.slack.api.Slack; import com.slack.api.methods.SlackApiException; import com.slack.api.model.User; import java.io.IOException; @@ -9,9 +10,8 @@ import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; import org.springframework.beans.factory.annotation.Value; -import com.slack.api.Slack; +import org.springframework.stereotype.Component; @Component diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java index edae181e..9210294a 100644 --- a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java @@ -14,11 +14,16 @@ import lombok.NoArgsConstructor; @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) @JsonInclude(JsonInclude.Include.NON_NULL) public class SlackBotMessageBlock { - private String type; // Example: button - private SlackMessageText text; // Should constitute of SlackBotMessageText + + private String type; // Example: button + private SlackMessageText text; // Should constitute of SlackBotMessageText private ArrayList elements; - public SlackBotMessageBlock(SlackMessageBlockType type, SlackMessageText text, ArrayList elements) { + public SlackBotMessageBlock( + SlackMessageBlockType type, + SlackMessageText text, + ArrayList elements + ) { this.type = type.type; this.text = text; this.elements = elements; diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java index 66fce767..afeb0499 100644 --- a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java @@ -11,18 +11,25 @@ import lombok.NoArgsConstructor; @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) @JsonInclude(JsonInclude.Include.NON_NULL) public class SlackMessageElement { - private String type; // Example: button - private SlackMessageText text; // Should constitute of SlackMessageText - private String style; // Example: primary, danger - private String value; - private String action_id; // Refers to slackbotclient's interna; action - public SlackMessageElement(SlackElementType type, SlackMessageText text, SlackElementStyle style, String value, String action_id) { + private String type; // Example: button + private SlackMessageText text; // Should constitute of SlackMessageText + private String style; // Example: primary, danger + private String value; + private String action_id; // Refers to slackbotclient's internal action_id + + public SlackMessageElement( + SlackElementType type, + SlackMessageText text, + SlackElementStyle style, + String value, + String actionId + ) { this.type = type.type; this.text = text; this.style = style.type; this.value = value; - this.action_id = action_id; + this.action_id = actionId; } /* elements": [ diff --git a/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java index 237b9a78..214f5cea 100644 --- a/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/role/RoleServiceImplTest.java @@ -6,6 +6,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import com.navi.infra.portal.domain.user.Privilege; import com.navi.infra.portal.domain.user.Role; import com.navi.infra.portal.v2.privilege.PrivilegeServiceImpl; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import org.junit.jupiter.api.DisplayName; @@ -93,9 +95,10 @@ class RoleServiceImplTest { null); var teamName = "team"; var actual = roleServiceImpl.createTeamRoleNames(teamName).collect(toList()); - var expected = List.of("team_dev_VIEWER", "team_dev_MAINTAINER", "team_dev_MANAGER", "team_dev_JITREADER, team_dev_JITREVIEWER", - "team_ALL_VIEWER", "team_ALL_MAINTAINER", "team_ALL_MANAGER", "team_ALL_JITREADER, team_ALL_JITREVIEWER"); - + var expected = new ArrayList<>(Arrays.asList("team_dev_VIEWER", "team_dev_MAINTAINER", + "team_dev_MANAGER", "team_dev_JITREADER", "team_dev_JITREVIEWER", "team_ALL_VIEWER", + "team_ALL_MAINTAINER", "team_ALL_MANAGER", "team_ALL_JITREADER", + "team_ALL_JITREVIEWER")); assertEquals(expected, actual); } } From d7d489f4f05c872ece2eebb868d80b5e89ead961 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Sat, 23 Mar 2024 15:33:18 +0530 Subject: [PATCH 012/108] INFRA-2219 | Harinder | Adding tests for improving coverage --- .../portal/v2/jit/dto/JitRequestDto.java | 2 +- .../portal/v2/jit/service/JitServiceImpl.java | 2 +- .../infra/portal/v2/jit/utils/AuthUtil.java | 10 +- .../v2/jit/service/JitServiceImplTest.java | 105 ++++++++++++++ .../portal/v2/jit/utils/AuthUtilTest.java | 131 ++++++++++++++++++ .../portal/v2/jit/utils/SlackBotUtilTest.java | 62 +++++++++ 6 files changed, 306 insertions(+), 6 deletions(-) create mode 100644 src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java create mode 100644 src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java create mode 100644 src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java diff --git a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java index 2d55246a..886d6cc5 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java @@ -33,7 +33,7 @@ public class JitRequestDto { private String resourceId; - private String resourceAction; // READ, WRITE, MASTER, ADMIN ETC + private String resourceAction; // read, write, master, admin ETC @Positive private Long grantWindow; diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 9516f76d..80376e39 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -81,7 +81,7 @@ public class JitServiceImpl implements JitService { jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingReviewers, approvedReviewers, rejectedReviewers, jitRequest.getStatus().toString()); String messageTimestamp = slackBotClient.postMessage( - userService.getSlackId(jitRequest.getRequestedBy().getEmail()), personalMessage); + userService.getSlackId(jitRequest.getRequestedFor().getEmail()), personalMessage); jitRequest.setPersonalSlackMessageTimestamp(messageTimestamp); return jitRequest; } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 2c2b090b..854e773c 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -32,8 +32,8 @@ public class AuthUtil { @Value("${jit.number_of_nonprod_approvals}") private Long nonprodJitApprovalsCount; - public boolean isAuthorized(String user, JitRequest jitRequest) { - List userRolesId = userService.listAllRolesOfUser(user); + public boolean isAuthorized(String userEmail, JitRequest jitRequest) { + List userRolesId = userService.listAllRolesOfUser(userEmail); List userRoles = roleService.listAllAuthorities(userRolesId); return userRoles.stream() @@ -48,7 +48,9 @@ public class AuthUtil { ) { return userService.findAllByIds( jitApprovalsRepository.findReviewersByAction(jitId, jitRequestStatus.toString())) - .parallelStream().map(User::getEmail).collect(Collectors.toList()); + .parallelStream() + .map(User::getEmail) + .collect(Collectors.toList()); } public Boolean checkRequiredApprovals(JitRequest jitRequest) { @@ -84,7 +86,7 @@ public class AuthUtil { reviewerRole = new Role( String.join("_", jitRequestDto.getTeam(), "ALL", JITREVIEWER.toString())); reviewers.addAll(userService.getUsersWithRole(reviewerRole.getName())); - + // TODO reduce number of userService calls thereby reducing DB calls return reviewers; } } diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java new file mode 100644 index 00000000..24eb5f21 --- /dev/null +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -0,0 +1,105 @@ +package com.navi.infra.portal.v2.jit.service; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.navi.infra.portal.domain.user.Team; +import com.navi.infra.portal.domain.user.User; +import com.navi.infra.portal.service.user.UserService; +import com.navi.infra.portal.v2.client.airflow.AirflowClient; +import com.navi.infra.portal.v2.jit.dto.JitRequestDto; +import com.navi.infra.portal.v2.jit.entity.Environment; +import com.navi.infra.portal.v2.jit.entity.JitApproval; +import com.navi.infra.portal.v2.jit.entity.JitRequest; +import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; +import com.navi.infra.portal.v2.jit.entity.Vertical; +import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; +import com.navi.infra.portal.v2.jit.repository.JitRequestsRepository; +import com.navi.infra.portal.v2.jit.utils.AuthUtil; +import com.navi.infra.portal.v2.jit.utils.SlackBotUtil; +import com.navi.infra.portal.v2.role.RoleService; +import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; +import com.navi.infra.portal.v2.team.TeamService; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.List; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.stubbing.Answer; + +public class JitServiceImplTest { + + private final JitRequestsRepository jitRequestRepository = mock(JitRequestsRepository.class); + private final JitApprovalsRepository jitApprovalsRepository = mock( + JitApprovalsRepository.class); + private final SlackBotUtil slackBotUtil = mock(SlackBotUtil.class); + private final AuthUtil authUtil = mock(AuthUtil.class); + + private final AirflowClient airflowClient = mock(AirflowClient.class); + private final SlackBotClient slackBotClient = mock(SlackBotClient.class); + + private final UserService userService = mock(UserService.class); + private final RoleService roleService = mock(RoleService.class); + private final TeamService teamService = mock(TeamService.class); + + JitServiceImpl jitServiceImpl = new JitServiceImpl(jitRequestRepository, jitApprovalsRepository, + slackBotUtil, authUtil, airflowClient, slackBotClient, userService, roleService, + teamService); + User requestedFor = new User(); + User requestedBy = new User(); + JitRequestDto jitRequestDto = new JitRequestDto("alpha@one.com", "beta@two.com", + Vertical.NAVIPAY, "Infra", Environment.PROD, "RDS", "dev-db", "read", 1L, null); + + + @Test + public void TestCreateJitRequest() throws IOException { + // Arrange + requestedFor.setEmail("alpha@one.com"); + requestedBy.setEmail("beta@two.com"); + JitRequest jitRequest = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, + new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, + 1L, LocalDateTime.now()); + JitRequest jitRequestWithId = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, + new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, + 1L, LocalDateTime.now()); + jitRequestWithId.setId(1L); + + User reviewerOne = new User(); + reviewerOne.setEmail("charlie@three.com"); + User reviewerTwo = new User(); + reviewerTwo.setEmail("delte@four.com"); + List reviewers = List.of(reviewerOne, reviewerTwo); + + JitApproval jitApprovalOne = new JitApproval(jitRequest, reviewerOne, + JitRequestStatus.PENDING); + JitApproval jitApprovalOneWithId = jitApprovalOne; + jitApprovalOneWithId.setId(1L); + jitApprovalOneWithId.setSlackMessageTimestamp("132413513"); + JitApproval jitApprovalTwo = new JitApproval(jitRequest, reviewerTwo, + JitRequestStatus.PENDING); + JitApproval jitApprovalTwoWithId = jitApprovalTwo; + jitApprovalTwoWithId.setId(1L); + jitApprovalTwoWithId.setSlackMessageTimestamp("132413513"); + List jitApprovals = List.of(jitApprovalOne, jitApprovalTwo); + List jitApprovalsWithId = List.of(jitApprovalOneWithId, jitApprovalTwoWithId); + + // Mock + when(userService.findUserByEmail("alpha@one.com")).thenReturn(requestedFor); + when(userService.findUserByEmail("beta@two.com")).thenReturn(requestedBy); + when(teamService.findByName("Infra")).thenReturn(new Team("Infra")); + when(authUtil.getReviewers(jitRequestDto)).thenReturn(reviewers); + when(jitRequestRepository.save(any())).thenReturn(jitRequestWithId); + when(userService.getSlackId(jitRequest.getRequestedFor().getEmail())).thenReturn("U12314"); + when(slackBotClient.postMessage(any(), any())).thenReturn("2341419824719"); + when(jitApprovalsRepository.saveAll(jitApprovals)).thenReturn(jitApprovalsWithId); + when(jitRequestRepository.save(jitRequest)).thenReturn(jitRequest); + + // Act + Boolean result = jitServiceImpl.createJitRequest(jitRequestDto); + + // Assert + Assertions.assertTrue(result); + } +} diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java new file mode 100644 index 00000000..7399e5f6 --- /dev/null +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -0,0 +1,131 @@ +package com.navi.infra.portal.v2.jit.utils; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.navi.infra.portal.domain.user.Team; +import com.navi.infra.portal.domain.user.User; +import com.navi.infra.portal.service.user.UserService; +import com.navi.infra.portal.v2.jit.dto.JitRequestDto; +import com.navi.infra.portal.v2.jit.entity.Environment; +import com.navi.infra.portal.v2.jit.entity.JitRequest; +import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; +import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; +import com.navi.infra.portal.v2.role.RoleService; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Assert; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.test.util.ReflectionTestUtils; + +public class AuthUtilTest { + + // Generate test cases for isAuthorized method + private final UserService userService = mock(UserService.class); + private final RoleService roleService = mock(RoleService.class); + private final JitApprovalsRepository jitApprovalsRepository = mock( + JitApprovalsRepository.class); + + AuthUtil authUtil = new AuthUtil(userService, roleService, jitApprovalsRepository); + + private User getTestUser() { + User testUser = new User(); + testUser.setEmail("harinder.singh@navi.com"); + testUser.setId(1L); + return testUser; + } + + @Test + public void testIsAuthorized() { + JitRequest jitRequest = new JitRequest(); + jitRequest.setTeam(new Team("TEAM")); + jitRequest.setEnvironment(Environment.PROD); + String userEmail = "alpha@one.com"; + List mockRoleIds = Collections.singletonList(123L); + List mockRoles = Collections.singletonList("TEAM_PROD_JITREVIEWER"); + + when(userService.listAllRolesOfUser(userEmail)).thenReturn(mockRoleIds); + when(roleService.listAllAuthorities(mockRoleIds)).thenReturn(mockRoles); + + assertTrue(authUtil.isAuthorized(userEmail, jitRequest)); + } + + @Test + public void testGetReviewersByAction() { + // Generate test cases for getReviewersByAction method + User testUser = getTestUser(); + + when(jitApprovalsRepository.findReviewersByAction(1L, "APPROVED")).thenReturn( + Collections.singletonList(1L)); + when(userService.findAllByIds(Collections.singletonList(1L))).thenReturn( + Collections.singletonList(testUser)); + + List reviewers = authUtil.getReviewersByAction(userService, 1L, + JitRequestStatus.APPROVED); + + Assert.assertEquals(List.of("harinder.singh@navi.com"), + authUtil.getReviewersByAction(userService, 1L, JitRequestStatus.APPROVED)); + } + + @Test + public void testCheckRequiredApprovalsProd() { + JitRequest jitRequest = new JitRequest(); + jitRequest.setEnvironment(Environment.PROD); + jitRequest.setId(1L); + + ReflectionTestUtils.setField(authUtil, "prodJitApprovalsCount", 2L); + + when(jitApprovalsRepository.findApprovedRequestsCount(jitRequest.getId())) + .thenReturn(2L); + + boolean result = authUtil.checkRequiredApprovals(jitRequest); + Assert.assertTrue(result); + } + + @Test + public void testCheckRequiredApprovalsNonprod() { + JitRequest jitRequest = new JitRequest(); + jitRequest.setEnvironment(Environment.DEV); + jitRequest.setId(1L); + + ReflectionTestUtils.setField(authUtil, "nonprodJitApprovalsCount", 1L); + + when(jitApprovalsRepository.findApprovedRequestsCount(jitRequest.getId())) + .thenReturn(1L); + + boolean result = authUtil.checkRequiredApprovals(jitRequest); + Assert.assertTrue(result); + } + + @Test + public void testGetReviewers() { + JitRequestDto mockRequestDto = new JitRequestDto(); + mockRequestDto.setTeam("Infra"); + mockRequestDto.setEnvironment(Environment.DEV); + + User reviewer1 = new User(); + reviewer1.setEmail("reviewer1@domain.com"); + User reviewer2 = new User(); + reviewer2.setEmail("reviewer2@domain.com"); + List specificRoleReviewers = new ArrayList<>(Arrays.asList(reviewer1)); + List allReviewers = Arrays.asList(reviewer2); + + when(userService.getUsersWithRole("Infra_dev_JITREVIEWER")) + .thenReturn(specificRoleReviewers); + when(userService.getUsersWithRole("Infra_ALL_JITREVIEWER")) + .thenReturn(allReviewers); + + // Execution + List result = authUtil.getReviewers(mockRequestDto); + + // Assertions + Assertions.assertEquals(2, result.size()); + Assertions.assertTrue(result.contains(reviewer1)); + Assertions.assertTrue(result.contains(reviewer2)); + } + +} diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java new file mode 100644 index 00000000..5f5b717a --- /dev/null +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java @@ -0,0 +1,62 @@ +package com.navi.infra.portal.v2.jit.utils; + +import com.navi.infra.portal.domain.user.Team; +import com.navi.infra.portal.domain.user.User; +import com.navi.infra.portal.v2.jit.entity.Environment; +import com.navi.infra.portal.v2.jit.entity.JitApproval; +import com.navi.infra.portal.v2.jit.entity.JitRequest; +import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; +import com.navi.infra.portal.v2.jit.entity.Vertical; +import com.navi.infra.portal.v2.slackbotclient.SlackBotAttachment; +import java.time.LocalDateTime; +import java.util.ArrayList; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Assertions; + +public class SlackBotUtilTest { + + private final SlackBotUtil slackBotUtil = new SlackBotUtil(); + + String userEmail = "test@domain.com"; + JitRequest jitRequest = new JitRequest(new User(), new User(), Vertical.SA, + new Team("Infra"), Environment.DEV, "RDS", "dev-db", + "read", JitRequestStatus.PENDING, 5L, LocalDateTime.now()); + JitApproval jitApproval = new JitApproval(); + + @Test + public void testGetReviewerMessage_ActionEnabled() { + // Setup (mock data for userEmail, JitRequest, JitApproval) + jitApproval.setAction(JitRequestStatus.PENDING); + jitApproval.setId(1L); + + // Call the method + SlackBotAttachment result = + slackBotUtil.getReviewerMessage(userEmail, jitRequest, jitApproval, true); + + // Assertions + Assertions.assertEquals(2, result.getBlocks().size()); // Section + action block + } + + @Test + public void testPersonalMessage_ActionEnabled() { + // Call the method + jitRequest.setId(2L); + SlackBotAttachment result = + slackBotUtil.getPersonalMessage(userEmail, jitRequest, true, + new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), "PENDING"); + + // Assertions + Assertions.assertEquals(2, result.getBlocks().size()); // Section + action block + } + + @Test + public void testGroupMessage() { + // Call the method + SlackBotAttachment result = + slackBotUtil.getGroupMessage(jitRequest, userEmail, new ArrayList<>(), + new ArrayList<>(), new ArrayList<>()); + + // Assertions + Assertions.assertEquals(1, result.getBlocks().size()); // Section + } +} \ No newline at end of file From aef64bc3dbd30b961aedc7e5643426059a2898b1 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Sat, 23 Mar 2024 16:23:24 +0530 Subject: [PATCH 013/108] INFRA-2219 | Harinder | Updating code to fix issues highlighted in sonarqube analysis. Removing /status api as each of the messages(reviewer, requestor and common channel) are updated on every action. --- .../v2/jit/controller/JitController.java | 24 +----- .../portal/v2/jit/service/JitService.java | 2 - .../portal/v2/jit/service/JitServiceImpl.java | 78 +++++++------------ .../infra/portal/v2/jit/utils/AuthUtil.java | 2 +- .../portal/v2/jit/utils/SlackBotUtil.java | 8 +- 5 files changed, 39 insertions(+), 75 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java index 502a52ab..8e7e161b 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java @@ -36,7 +36,7 @@ public class JitController { ? ResponseEntity.status(HttpStatus.CREATED).build() : ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } catch (IllegalArgumentException | IOException ex) { - log.error("Exception: ", ex.getMessage()); + log.error(ex.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } @@ -51,7 +51,7 @@ public class JitController { ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() : ResponseEntity.status(HttpStatus.OK).build(); } catch (Exception ex) { - log.error("Exception: ", ex.getMessage()); + log.error(ex.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } @@ -66,27 +66,11 @@ public class JitController { ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() : ResponseEntity.status(HttpStatus.OK).build(); } catch (Exception ex) { - log.error("Exception: ", ex.getMessage()); + log.error(ex.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } - /* - @PostMapping("/status/{id}") - public ResponseEntity getJitRequestStatus(@RequestBody JitUserDTO checker, - @PathVariable Long id) { - try { - JitResponseDTO jitResponse = jitService.getJitRequestStatus(checker.getUser(), id); - return jitResponse.getId() == -1 - ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() - : ResponseEntity.ok(jitResponse); - } catch (Exception ex) { - log.error("Exception: ", ex.getMessage()); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); - } - } - */ - @PostMapping("/close/{id}") public ResponseEntity closeJitRequest( @RequestBody JitUserDto closer, @@ -98,7 +82,7 @@ public class JitController { ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() : ResponseEntity.status(HttpStatus.OK).build(); } catch (Exception ex) { - log.error("Exception: ", ex.getMessage()); + log.error(ex.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java index 809b6a58..cfe966f3 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java @@ -12,7 +12,5 @@ public interface JitService { Integer rejectJitRequest(String rejecter, Long requestId) throws IOException; - // JitResponseDTO getJitRequestStatus(String checker, Long requestId); - JitResponseDto closeRequest(String closer, Long requestId); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 80376e39..6810ff7e 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -47,6 +47,8 @@ public class JitServiceImpl implements JitService { private final ResourceType resourceType = null; private final String env = null; + private static final String ExceptionAirflowOrDb = "Failed to connect to airflow or failed to flush to DB"; + @Value("${jit.dag.id}") private String dagId; @@ -69,7 +71,7 @@ public class JitServiceImpl implements JitService { jitApprovalsRepository.save(jitApproval); } - private JitRequest updatePersonalMessageOnSlack( + private void updatePersonalMessageOnSlack( JitRequest jitRequest, List pendingReviewers, List approvedReviewers, @@ -83,10 +85,9 @@ public class JitServiceImpl implements JitService { String messageTimestamp = slackBotClient.postMessage( userService.getSlackId(jitRequest.getRequestedFor().getEmail()), personalMessage); jitRequest.setPersonalSlackMessageTimestamp(messageTimestamp); - return jitRequest; } - private JitRequest updateGroupMessageOnSlack( + private void updateGroupMessageOnSlack( JitRequest jitRequest, List pendingReviewers, List approvedReviewers, @@ -98,7 +99,6 @@ public class JitServiceImpl implements JitService { rejectedReviewers); String messageTimestamp = slackBotClient.postMessage(commonChannelId, commonChannelMessage); jitRequest.setGroupSlackMessageTimestamp(messageTimestamp); - return jitRequest; } private Integer processJitRequest( @@ -159,7 +159,7 @@ public class JitServiceImpl implements JitService { try { approvedReviewers.add(reviewerEmail); - Boolean actionEnabled = true; + boolean actionEnabled = true; if (authUtil.checkRequiredApprovals(jitRequest)) { // if required number of approvals are met, // 1. schedule JIT(just in time) DAGs - one for grant and another for grant, @@ -169,6 +169,7 @@ public class JitServiceImpl implements JitService { jitRequest.getTeam().getName(), jitRequest.getEnvironment().toString(), jitRequest.getRequestedFor().getEmail(), jitRequest.getResourceType(), jitRequest.getResourceAction()); + validateGrantTime(jitRequest); airflowClient.triggerJitDag(jitRequest, dagId, runId + "grant", "grant"); airflowClient.triggerJitDag(jitRequest, dagId, runId + "revoke", "revoke"); @@ -180,20 +181,29 @@ public class JitServiceImpl implements JitService { updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); // send group message to common channel with details on pending and approved reviewers - jitRequest = updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, + updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); - jitRequest = updatePersonalMessageOnSlack(jitRequest, pendingReviewers, + updatePersonalMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers, actionEnabled); jitRequestRepository.save(jitRequest); jitApprovalsRepository.save(jitApproval); return 0; } catch (Exception e) { - log.error("Failed to connect to airflow or failed to flush to DB", e.getCause()); + log.error(ExceptionAirflowOrDb, e.getCause()); return -1; } } + private void validateGrantTime(JitRequest jitRequest) { + jitRequest.setGrantAt(jitRequest.getGrantAt() == null + ? LocalDateTime.now() + : jitRequest.getGrantAt()); + jitRequest.setGrantAt(jitRequest.getGrantAt().isBefore(LocalDateTime.now()) + ? LocalDateTime.now() + : jitRequest.getGrantAt()); + } + private Integer jitRejectedFlow( String reviewerEmail, JitApproval jitApproval, @@ -209,9 +219,9 @@ public class JitServiceImpl implements JitService { jitRequest.setStatus(JitRequestStatus.REJECTED); updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); - jitRequest = updatePersonalMessageOnSlack(jitRequest, pendingReviewers, + updatePersonalMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers, false); - jitRequest = updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, + updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); jitApprovalsRepository.save(jitApproval); @@ -219,14 +229,12 @@ public class JitServiceImpl implements JitService { return 0; } catch (Exception e) { - log.error("Failed to connect to airflow or failed to flush to DB", e.getCause()); + log.error(ExceptionAirflowOrDb, e.getCause()); return -1; } } - private Integer jitCancelledFlow( - String closerEmail, JitRequest jitRequest - ) { + private Integer jitCancelledFlow(JitRequest jitRequest) { try { jitRequest.setStatus(JitRequestStatus.CANCELLED); List jitApprovals = jitApprovalsRepository.findAllReviewsByJitId( @@ -238,14 +246,14 @@ public class JitServiceImpl implements JitService { updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); } - jitRequest = updateGroupMessageOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), + updateGroupMessageOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); - jitRequest = updatePersonalMessageOnSlack(jitRequest, new ArrayList<>(), + updatePersonalMessageOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), false); jitRequestRepository.save(jitRequest); return 0; } catch (Exception e) { - log.error("Failed to connect to airflow or failed to flush to DB", e.getCause()); + log.error(ExceptionAirflowOrDb, e.getCause()); return -1; } } @@ -261,17 +269,9 @@ public class JitServiceImpl implements JitService { @Override public Boolean createJitRequest(JitRequestDto jitRequestDto) throws IOException { - // validations here - if (jitRequestDto.getGrantAt() == null) { - jitRequestDto.setGrantAt(LocalDateTime.now()); - } else if (jitRequestDto.getGrantAt().isBefore(LocalDateTime.now())) { - log.error("Invalid time: {} is before now {}", jitRequestDto.getGrantAt(), - LocalDateTime.now()); - return false; - } - // Map request DTO to JitRequest Entity and save in DB JitRequest jitRequest = mapToJitRequest(jitRequestDto); + validateGrantTime(jitRequest); // Determine the reviewers based on REQUEST List reviewers = authUtil.getReviewers(jitRequestDto); @@ -296,11 +296,11 @@ public class JitServiceImpl implements JitService { // send personal message to user with details on pending and approved reviewers JitRequest jitRequestWithId = jitRequestRepository.save(jitRequest); - jitRequest = updatePersonalMessageOnSlack(jitRequestWithId, pendingReviewers, + updatePersonalMessageOnSlack(jitRequestWithId, pendingReviewers, new ArrayList<>(), new ArrayList<>(), true); // send group message to common channel with details on pending and approved reviewers - jitRequest = updateGroupMessageOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), + updateGroupMessageOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), new ArrayList<>()); List jitApprovalsWithId = jitApprovalsRepository.saveAll(jitApprovals); @@ -330,33 +330,13 @@ public class JitServiceImpl implements JitService { this::jitRejectedFlow); } - /* - @Override - public JitResponseDTO getJitRequestStatus(String checker, Long requestId) { - // verify if checker does have to permission to read JIT requests, - // if so then inform about pending reviews - Optional jitRequests = jitRequestRepository.findById(requestId); - if (jitRequests.isPresent()) { - JitRequest jR = jitRequests.get(); - if (jR.getRequestedFor().getEmail().equals(checker)) { - // use slackClient to update original message as well - return new JitResponseDTO(jR.getId(), jR.getStatus(), new ArrayList<>()); - } else { - log.error("User {} not allowed to check request status", checker); - return new JitResponseDTO(-1, null, null); - } - } - return new JitResponseDTO(-1, null, null); - } - */ - @Override public JitResponseDto closeRequest(String closer, Long requestId) { Optional jitRequests = jitRequestRepository.findById(requestId); if (jitRequests.isPresent()) { JitRequest jitRequest = jitRequests.get(); if (jitRequest.getRequestedFor().getEmail().equals(closer)) { - jitCancelledFlow(closer, jitRequest); + jitCancelledFlow(jitRequest); } else { log.error("User {} not allowed to close request", closer); return new JitResponseDto(-1, null, null); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 854e773c..4ee4e26d 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -53,7 +53,7 @@ public class AuthUtil { .collect(Collectors.toList()); } - public Boolean checkRequiredApprovals(JitRequest jitRequest) { + public boolean checkRequiredApprovals(JitRequest jitRequest) { Environment env = jitRequest.getEnvironment(); Long approvedRequests = jitApprovalsRepository.findApprovedRequestsCount( jitRequest.getId()); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index 5d1a1ba8..c07638bc 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -18,6 +18,8 @@ import org.springframework.stereotype.Component; @Component public class SlackBotUtil { + private static final String SlackYellow = "#f2c744"; + public SlackBotAttachment getReviewerMessage( String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled ) { @@ -60,7 +62,7 @@ public class SlackBotUtil { blocks.add(reviewRequestAction); } - return new SlackBotAttachment("#f2c744", blocks); + return new SlackBotAttachment(SlackYellow, blocks); } public SlackBotAttachment getPersonalMessage( @@ -97,7 +99,7 @@ public class SlackBotUtil { blocks.add(reviewRequestAction); } - return new SlackBotAttachment("#f2c744", blocks); + return new SlackBotAttachment(SlackYellow, blocks); } public SlackBotAttachment getGroupMessage( @@ -119,6 +121,6 @@ public class SlackBotUtil { ArrayList blocks = new ArrayList<>(); blocks.add(reviewRequestSection); - return new SlackBotAttachment("#f2c744", blocks); + return new SlackBotAttachment(SlackYellow, blocks); } } From c6d04e55c22f3398db132a8ae17dd4baf22ce365 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Wed, 27 Mar 2024 15:54:29 +0530 Subject: [PATCH 014/108] INFRA-2219 | Harinder | Addressing comments wrt slack message naming and adding display names in tests --- .../portal/v2/jit/dto/JitRequestDto.java | 2 +- .../portal/v2/jit/entity/JitApproval.java | 2 +- .../portal/v2/jit/entity/JitRequest.java | 4 +- .../infra/portal/v2/jit/entity/Vertical.java | 5 +- .../portal/v2/jit/service/JitServiceImpl.java | 64 +++++++++---------- .../portal/v2/jit/utils/SlackBotUtil.java | 6 +- ...V1.69__Add_just_in_time_requests_table.sql | 4 +- ...1.70__Add_just_in_time_approvals_table.sql | 2 +- .../v2/jit/service/JitServiceImplTest.java | 4 +- .../portal/v2/jit/utils/AuthUtilTest.java | 9 ++- .../portal/v2/jit/utils/SlackBotUtilTest.java | 15 ++--- 11 files changed, 57 insertions(+), 60 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java index 886d6cc5..ccdd7668 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java @@ -38,5 +38,5 @@ public class JitRequestDto { @Positive private Long grantWindow; - private LocalDateTime grantAt; + private Long grantAt; } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java index 03d5353d..cdec3b33 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java @@ -49,7 +49,7 @@ public class JitApproval extends BaseEntity { @Column(nullable = false) private JitRequestStatus action; - private String slackMessageTimestamp; + private String reviewerSlackMessageTimestamp; public JitApproval(JitRequest jitRequest, User reviewer, JitRequestStatus action) { this.jitRequest = jitRequest; diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java index ee84d5c3..016df0e6 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java @@ -64,9 +64,9 @@ public class JitRequest extends BaseEntity { private LocalDateTime grantAt; - private String personalSlackMessageTimestamp; + private String requestorSlackMessageTimestamp; - private String groupSlackMessageTimestamp; + private String channelSlackMessageTimestamp; public JitRequest( User requestedFor, diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java index aa4dba41..b1f3a81f 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java @@ -1,11 +1,12 @@ package com.navi.infra.portal.v2.jit.entity; public enum Vertical { - GI("GI"), + INSURANCE("Insurance"), NAVIPAY("navi-pay"), SA("sa"), LENDING("lending"), - NAVIPPL("navi-ppl"); + NAVIPPL("navi-ppl"), + AMC("lenging"); // intentional mapping public final String type; diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 6810ff7e..8a075ead 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -18,7 +18,9 @@ import com.navi.infra.portal.v2.slackbotclient.SlackBotAttachment; import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; import com.navi.infra.portal.v2.team.TeamService; import java.io.IOException; +import java.time.Instant; import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -32,46 +34,41 @@ import org.springframework.stereotype.Service; @Slf4j public class JitServiceImpl implements JitService { + private static final String ExceptionAirflowOrDb = "Failed to connect to airflow or failed to flush to DB"; private final JitRequestsRepository jitRequestRepository; private final JitApprovalsRepository jitApprovalsRepository; private final SlackBotUtil slackBotUtil; private final AuthUtil authUtil; - private final AirflowClient airflowClient; private final SlackBotClient slackBotClient; - private final UserService userService; private final RoleService roleService; private final TeamService teamService; - private final ResourceType resourceType = null; private final String env = null; - - private static final String ExceptionAirflowOrDb = "Failed to connect to airflow or failed to flush to DB"; - @Value("${jit.dag.id}") private String dagId; @Value("${jit.slack.common.channel.id}") private String commonChannelId; - private void updateReviewerMessageOnSlack( + private void updateReviewerDMOnSlack( User reviewer, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled ) throws IOException { - SlackBotAttachment reviewMessage = slackBotUtil.getReviewerMessage( + SlackBotAttachment reviewMessage = slackBotUtil.getReviewerDM( jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled); String messageTimestamp = slackBotClient.postMessage( userService.getSlackId(reviewer.getEmail()), reviewMessage); - jitApproval.setSlackMessageTimestamp(messageTimestamp); + jitApproval.setReviewerSlackMessageTimestamp(messageTimestamp); jitApprovalsRepository.save(jitApproval); } - private void updatePersonalMessageOnSlack( + private void updateRequestorDMOnSlack( JitRequest jitRequest, List pendingReviewers, List approvedReviewers, @@ -79,26 +76,26 @@ public class JitServiceImpl implements JitService { boolean actionEnabled ) throws IOException { - SlackBotAttachment personalMessage = slackBotUtil.getPersonalMessage( + SlackBotAttachment personalMessage = slackBotUtil.getRequestorDM( jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingReviewers, approvedReviewers, rejectedReviewers, jitRequest.getStatus().toString()); String messageTimestamp = slackBotClient.postMessage( userService.getSlackId(jitRequest.getRequestedFor().getEmail()), personalMessage); - jitRequest.setPersonalSlackMessageTimestamp(messageTimestamp); + jitRequest.setRequestorSlackMessageTimestamp(messageTimestamp); } - private void updateGroupMessageOnSlack( + private void updateChannelOnSlack( JitRequest jitRequest, List pendingReviewers, List approvedReviewers, List rejectedReviewers ) throws IOException { - SlackBotAttachment commonChannelMessage = slackBotUtil.getGroupMessage(jitRequest, + SlackBotAttachment commonChannelMessage = slackBotUtil.getChannelMessage(jitRequest, jitRequest.getRequestedFor().getEmail(), pendingReviewers, approvedReviewers, rejectedReviewers); String messageTimestamp = slackBotClient.postMessage(commonChannelId, commonChannelMessage); - jitRequest.setGroupSlackMessageTimestamp(messageTimestamp); + jitRequest.setChannelSlackMessageTimestamp(messageTimestamp); } private Integer processJitRequest( @@ -170,20 +167,20 @@ public class JitServiceImpl implements JitService { jitRequest.getRequestedFor().getEmail(), jitRequest.getResourceType(), jitRequest.getResourceAction()); validateGrantTime(jitRequest); - airflowClient.triggerJitDag(jitRequest, dagId, runId + "grant", "grant"); - airflowClient.triggerJitDag(jitRequest, dagId, runId + "revoke", "revoke"); + airflowClient.triggerJitDag(jitRequest, dagId, runId + "-grant", "grant"); + airflowClient.triggerJitDag(jitRequest, dagId, runId + "-revoke", "revoke"); jitRequest.setStatus(JitRequestStatus.APPROVED); actionEnabled = false; } // inform reviewer on slack that request is approved and remove action buttons - updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + updateReviewerDMOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); // send group message to common channel with details on pending and approved reviewers - updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, + updateChannelOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); - updatePersonalMessageOnSlack(jitRequest, pendingReviewers, + updateRequestorDMOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers, actionEnabled); jitRequestRepository.save(jitRequest); @@ -218,10 +215,10 @@ public class JitServiceImpl implements JitService { jitApproval.setAction(JitRequestStatus.REJECTED); jitRequest.setStatus(JitRequestStatus.REJECTED); - updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); - updatePersonalMessageOnSlack(jitRequest, pendingReviewers, + updateReviewerDMOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + updateRequestorDMOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers, false); - updateGroupMessageOnSlack(jitRequest, pendingReviewers, approvedReviewers, + updateChannelOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); jitApprovalsRepository.save(jitApproval); @@ -243,12 +240,12 @@ public class JitServiceImpl implements JitService { jitApproval.setReviewedAt(LocalDateTime.now()); jitApproval.setAction(JitRequestStatus.CANCELLED); jitApprovalsRepository.save(jitApproval); - updateReviewerMessageOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, + updateReviewerDMOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); } - updateGroupMessageOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), + updateChannelOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); - updatePersonalMessageOnSlack(jitRequest, new ArrayList<>(), + updateRequestorDMOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), false); jitRequestRepository.save(jitRequest); return 0; @@ -264,14 +261,16 @@ public class JitServiceImpl implements JitService { jitRequestDto.getVertical(), teamService.findByName(jitRequestDto.getTeam()), jitRequestDto.getEnvironment(), jitRequestDto.getResourceType(), jitRequestDto.getResourceId(), jitRequestDto.getResourceAction(), - JitRequestStatus.PENDING, jitRequestDto.getGrantWindow(), jitRequestDto.getGrantAt()); + JitRequestStatus.PENDING, jitRequestDto.getGrantWindow(), + jitRequestDto.getGrantAt() == null ? LocalDateTime.now() : + Instant.ofEpochSecond(jitRequestDto.getGrantAt()).atZone(ZoneId.systemDefault()) + .toLocalDateTime()); } @Override public Boolean createJitRequest(JitRequestDto jitRequestDto) throws IOException { // Map request DTO to JitRequest Entity and save in DB JitRequest jitRequest = mapToJitRequest(jitRequestDto); - validateGrantTime(jitRequest); // Determine the reviewers based on REQUEST List reviewers = authUtil.getReviewers(jitRequestDto); @@ -296,18 +295,18 @@ public class JitServiceImpl implements JitService { // send personal message to user with details on pending and approved reviewers JitRequest jitRequestWithId = jitRequestRepository.save(jitRequest); - updatePersonalMessageOnSlack(jitRequestWithId, pendingReviewers, + updateRequestorDMOnSlack(jitRequestWithId, pendingReviewers, new ArrayList<>(), new ArrayList<>(), true); // send group message to common channel with details on pending and approved reviewers - updateGroupMessageOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), + updateChannelOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), new ArrayList<>()); List jitApprovalsWithId = jitApprovalsRepository.saveAll(jitApprovals); JitRequest finalJitRequest = jitRequest; jitApprovalsWithId.stream().forEach(jitApproval -> { try { - updateReviewerMessageOnSlack(jitApproval.getReviewer(), + updateReviewerDMOnSlack(jitApproval.getReviewer(), finalJitRequest, jitApproval, true); } catch (IOException e) { throw new RuntimeException(e); @@ -335,7 +334,8 @@ public class JitServiceImpl implements JitService { Optional jitRequests = jitRequestRepository.findById(requestId); if (jitRequests.isPresent()) { JitRequest jitRequest = jitRequests.get(); - if (jitRequest.getRequestedFor().getEmail().equals(closer)) { + if (jitRequest.getRequestedFor().getEmail().equals(closer) && jitRequest.getStatus() + .equals(JitRequestStatus.PENDING)) { jitCancelledFlow(jitRequest); } else { log.error("User {} not allowed to close request", closer); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index c07638bc..325b4fc7 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -20,7 +20,7 @@ public class SlackBotUtil { private static final String SlackYellow = "#f2c744"; - public SlackBotAttachment getReviewerMessage( + public SlackBotAttachment getReviewerDM( String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled ) { ArrayList blocks = new ArrayList<>(); @@ -65,7 +65,7 @@ public class SlackBotUtil { return new SlackBotAttachment(SlackYellow, blocks); } - public SlackBotAttachment getPersonalMessage( + public SlackBotAttachment getRequestorDM( String userEmail, JitRequest jitRequest, Boolean actionEnabled, @@ -102,7 +102,7 @@ public class SlackBotUtil { return new SlackBotAttachment(SlackYellow, blocks); } - public SlackBotAttachment getGroupMessage( + public SlackBotAttachment getChannelMessage( JitRequest jitRequest, String email, List pendingReviewers, diff --git a/src/main/resources/db/migration/V1.69__Add_just_in_time_requests_table.sql b/src/main/resources/db/migration/V1.69__Add_just_in_time_requests_table.sql index c40a4f2b..9aec8e93 100644 --- a/src/main/resources/db/migration/V1.69__Add_just_in_time_requests_table.sql +++ b/src/main/resources/db/migration/V1.69__Add_just_in_time_requests_table.sql @@ -13,6 +13,6 @@ CREATE TABLE jit_requests ( status character varying(255) NOT NULL, grant_window BIGINT NOT NULL, grant_at timestamp without time zone, - personal_slack_message_timestamp character varying(255), - group_slack_message_timestamp character varying(255) + requestor_slack_message_timestamp character varying(255), + channel_slack_message_timestamp character varying(255) ); \ No newline at end of file diff --git a/src/main/resources/db/migration/V1.70__Add_just_in_time_approvals_table.sql b/src/main/resources/db/migration/V1.70__Add_just_in_time_approvals_table.sql index 1daa6d9a..9a51ed13 100644 --- a/src/main/resources/db/migration/V1.70__Add_just_in_time_approvals_table.sql +++ b/src/main/resources/db/migration/V1.70__Add_just_in_time_approvals_table.sql @@ -6,5 +6,5 @@ CREATE TABLE jit_approvals ( reviewer_id BIGINT NOT NULL REFERENCES users(id), reviewed_at timestamp without time zone, action character varying(255) NOT NULL, - slack_message_timestamp character varying(255) + reviewer_slack_message_timestamp character varying(255) ); \ No newline at end of file diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java index 24eb5f21..2ffb201d 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -76,12 +76,12 @@ public class JitServiceImplTest { JitRequestStatus.PENDING); JitApproval jitApprovalOneWithId = jitApprovalOne; jitApprovalOneWithId.setId(1L); - jitApprovalOneWithId.setSlackMessageTimestamp("132413513"); + jitApprovalOneWithId.setReviewerSlackMessageTimestamp("132413513"); JitApproval jitApprovalTwo = new JitApproval(jitRequest, reviewerTwo, JitRequestStatus.PENDING); JitApproval jitApprovalTwoWithId = jitApprovalTwo; jitApprovalTwoWithId.setId(1L); - jitApprovalTwoWithId.setSlackMessageTimestamp("132413513"); + jitApprovalTwoWithId.setReviewerSlackMessageTimestamp("132413513"); List jitApprovals = List.of(jitApprovalOne, jitApprovalTwo); List jitApprovalsWithId = List.of(jitApprovalOneWithId, jitApprovalTwoWithId); diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java index 7399e5f6..11d120d4 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.List; import org.junit.Assert; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.test.util.ReflectionTestUtils; @@ -40,6 +41,7 @@ public class AuthUtilTest { } @Test + @DisplayName("Check if the user authorized and has specific role") public void testIsAuthorized() { JitRequest jitRequest = new JitRequest(); jitRequest.setTeam(new Team("TEAM")); @@ -55,6 +57,7 @@ public class AuthUtilTest { } @Test + @DisplayName("Should be able to fetch reviewers who have APPROVED request") public void testGetReviewersByAction() { // Generate test cases for getReviewersByAction method User testUser = getTestUser(); @@ -64,14 +67,12 @@ public class AuthUtilTest { when(userService.findAllByIds(Collections.singletonList(1L))).thenReturn( Collections.singletonList(testUser)); - List reviewers = authUtil.getReviewersByAction(userService, 1L, - JitRequestStatus.APPROVED); - Assert.assertEquals(List.of("harinder.singh@navi.com"), authUtil.getReviewersByAction(userService, 1L, JitRequestStatus.APPROVED)); } @Test + @DisplayName("Should be able to check if the request has enough approvals as per environment PROD") public void testCheckRequiredApprovalsProd() { JitRequest jitRequest = new JitRequest(); jitRequest.setEnvironment(Environment.PROD); @@ -87,6 +88,7 @@ public class AuthUtilTest { } @Test + @DisplayName("Should be able to check if the request has enough approvals as per environment NONPROD") public void testCheckRequiredApprovalsNonprod() { JitRequest jitRequest = new JitRequest(); jitRequest.setEnvironment(Environment.DEV); @@ -102,6 +104,7 @@ public class AuthUtilTest { } @Test + @DisplayName("Should be able to get reviewers for certain combination of team and environment") public void testGetReviewers() { JitRequestDto mockRequestDto = new JitRequestDto(); mockRequestDto.setTeam("Infra"); diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java index 5f5b717a..e439f0bc 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java @@ -10,8 +10,8 @@ import com.navi.infra.portal.v2.jit.entity.Vertical; import com.navi.infra.portal.v2.slackbotclient.SlackBotAttachment; import java.time.LocalDateTime; import java.util.ArrayList; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class SlackBotUtilTest { @@ -25,38 +25,31 @@ public class SlackBotUtilTest { @Test public void testGetReviewerMessage_ActionEnabled() { - // Setup (mock data for userEmail, JitRequest, JitApproval) jitApproval.setAction(JitRequestStatus.PENDING); jitApproval.setId(1L); - // Call the method SlackBotAttachment result = - slackBotUtil.getReviewerMessage(userEmail, jitRequest, jitApproval, true); + slackBotUtil.getReviewerDM(userEmail, jitRequest, jitApproval, true); - // Assertions Assertions.assertEquals(2, result.getBlocks().size()); // Section + action block } @Test public void testPersonalMessage_ActionEnabled() { - // Call the method jitRequest.setId(2L); SlackBotAttachment result = - slackBotUtil.getPersonalMessage(userEmail, jitRequest, true, + slackBotUtil.getRequestorDM(userEmail, jitRequest, true, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), "PENDING"); - // Assertions Assertions.assertEquals(2, result.getBlocks().size()); // Section + action block } @Test public void testGroupMessage() { - // Call the method SlackBotAttachment result = - slackBotUtil.getGroupMessage(jitRequest, userEmail, new ArrayList<>(), + slackBotUtil.getChannelMessage(jitRequest, userEmail, new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); - // Assertions Assertions.assertEquals(1, result.getBlocks().size()); // Section } } \ No newline at end of file From 07957b2973773c0a9e42994e04d1253b80baea0c Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Wed, 27 Mar 2024 16:08:11 +0530 Subject: [PATCH 015/108] INFRA-2219 | Harinder | Updating db migration script number post merge --- ...uests_table.sql => V1.70__Add_just_in_time_requests_table.sql} | 0 ...vals_table.sql => V1.71__Add_just_in_time_approvals_table.sql} | 0 ...t_roles_privileges.sql => V1.73__Add_jit_roles_privileges.sql} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{V1.69__Add_just_in_time_requests_table.sql => V1.70__Add_just_in_time_requests_table.sql} (100%) rename src/main/resources/db/migration/{V1.70__Add_just_in_time_approvals_table.sql => V1.71__Add_just_in_time_approvals_table.sql} (100%) rename src/main/resources/db/migration/{V1.71__Add_jit_roles_privileges.sql => V1.73__Add_jit_roles_privileges.sql} (100%) diff --git a/src/main/resources/db/migration/V1.69__Add_just_in_time_requests_table.sql b/src/main/resources/db/migration/V1.70__Add_just_in_time_requests_table.sql similarity index 100% rename from src/main/resources/db/migration/V1.69__Add_just_in_time_requests_table.sql rename to src/main/resources/db/migration/V1.70__Add_just_in_time_requests_table.sql diff --git a/src/main/resources/db/migration/V1.70__Add_just_in_time_approvals_table.sql b/src/main/resources/db/migration/V1.71__Add_just_in_time_approvals_table.sql similarity index 100% rename from src/main/resources/db/migration/V1.70__Add_just_in_time_approvals_table.sql rename to src/main/resources/db/migration/V1.71__Add_just_in_time_approvals_table.sql diff --git a/src/main/resources/db/migration/V1.71__Add_jit_roles_privileges.sql b/src/main/resources/db/migration/V1.73__Add_jit_roles_privileges.sql similarity index 100% rename from src/main/resources/db/migration/V1.71__Add_jit_roles_privileges.sql rename to src/main/resources/db/migration/V1.73__Add_jit_roles_privileges.sql From 2fa79dca139a0cc9ac27f2358dd68077e55c183b Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 28 Mar 2024 18:37:52 +0530 Subject: [PATCH 016/108] INFRA-2219 | Harinder | Handling case where there are no reviewers. Sending review request to unique list of reviewers as one could have multiple applicable roles --- .../portal/service/user/UserService.java | 4 -- .../v2/client/airflow/AirflowClient.java | 1 - .../repository/JitApprovalsRepository.java | 2 +- .../portal/v2/jit/service/JitServiceImpl.java | 52 ++++++++++++------- .../infra/portal/v2/jit/utils/AuthUtil.java | 9 +++- .../portal/v2/jit/utils/SlackBotUtil.java | 32 +++++++++--- .../portal/v2/jit/utils/SlackBotUtilTest.java | 4 +- 7 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/service/user/UserService.java b/src/main/java/com/navi/infra/portal/service/user/UserService.java index 1b868f0c..90d6dce3 100644 --- a/src/main/java/com/navi/infra/portal/service/user/UserService.java +++ b/src/main/java/com/navi/infra/portal/service/user/UserService.java @@ -320,10 +320,6 @@ public class UserService { return userRepository.findAllById(userIds); } - public List listAllRolesOfUser(Long userId) { - return userRepository.findAllRolesOfUser(userId); - } - public List listAllRolesOfUser(String email) { Long id = userRepository.findIdByEmail(email); return userRepository.findAllRolesOfUser(id); diff --git a/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java b/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java index d930733b..5b2cbd5e 100644 --- a/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java +++ b/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java @@ -110,7 +110,6 @@ public class AirflowClient { "team", jitRequest.getTeam().getName(), "env", jitRequest.getEnvironment().toString(), "resource_type", jitRequest.getResourceType(), - "resource_id", jitRequest.getResourceId(), "user", jitRequest.getRequestedFor().getEmail(), "resource_action", jitRequest.getResourceAction(), "action", action diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java index de92422b..5c8e482b 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java @@ -17,7 +17,7 @@ public interface JitApprovalsRepository extends JpaRepository nativeQuery = true) List findAllReviewsByJitId(Long jitId); - @Query(value = "SELECT COUNT(ja.reviewer_id) FROM jit_approvals ja WHERE ja.jit_id = :jitId", + @Query(value = "SELECT COUNT(ja.reviewer_id) FROM jit_approvals ja WHERE ja.jit_id = :jitId AND ja.action = 'APPROVED'", nativeQuery = true) Long findApprovedRequestsCount(Long jitId); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 8a075ead..ee7d18bd 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -24,6 +24,7 @@ import java.time.ZoneId; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -34,7 +35,8 @@ import org.springframework.stereotype.Service; @Slf4j public class JitServiceImpl implements JitService { - private static final String ExceptionAirflowOrDb = "Failed to connect to airflow or failed to flush to DB"; + private static final String ExceptionAirflowOrDb = + "Failed to connect to airflow or failed to flush to DB"; private final JitRequestsRepository jitRequestRepository; private final JitApprovalsRepository jitApprovalsRepository; private final SlackBotUtil slackBotUtil; @@ -52,14 +54,14 @@ public class JitServiceImpl implements JitService { @Value("${jit.slack.common.channel.id}") private String commonChannelId; - private void updateReviewerDMOnSlack( + private void updateReviewerDmOnSlack( User reviewer, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled ) throws IOException { - SlackBotAttachment reviewMessage = slackBotUtil.getReviewerDM( + SlackBotAttachment reviewMessage = slackBotUtil.getReviewerDm( jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled); String messageTimestamp = slackBotClient.postMessage( userService.getSlackId(reviewer.getEmail()), reviewMessage); @@ -68,7 +70,7 @@ public class JitServiceImpl implements JitService { jitApprovalsRepository.save(jitApproval); } - private void updateRequestorDMOnSlack( + private void updateRequestorDmOnSlack( JitRequest jitRequest, List pendingReviewers, List approvedReviewers, @@ -76,7 +78,7 @@ public class JitServiceImpl implements JitService { boolean actionEnabled ) throws IOException { - SlackBotAttachment personalMessage = slackBotUtil.getRequestorDM( + SlackBotAttachment personalMessage = slackBotUtil.getRequestorDm( jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingReviewers, approvedReviewers, rejectedReviewers, jitRequest.getStatus().toString()); String messageTimestamp = slackBotClient.postMessage( @@ -84,6 +86,12 @@ public class JitServiceImpl implements JitService { jitRequest.setRequestorSlackMessageTimestamp(messageTimestamp); } + private void updateRequestorNoReviewersDmOnSlack(JitRequest jitRequest) throws IOException { + SlackBotAttachment personalMessage = slackBotUtil.getRequestorNoReviewerDm(jitRequest); + slackBotClient.postMessage( + userService.getSlackId(jitRequest.getRequestedFor().getEmail()), personalMessage); + } + private void updateChannelOnSlack( JitRequest jitRequest, List pendingReviewers, @@ -127,6 +135,9 @@ public class JitServiceImpl implements JitService { jitApproval.setReviewer(userService.findUserByEmail(reviewerEmail)); jitApproval.setAction(jitRequestStatus); + jitApprovalsRepository.save(jitApproval); + // reviewer lists(pending, approved, rejected) and count of approvals depends on above + List pendingReviewers = authUtil.getReviewersByAction(userService, jitRequest.getId(), JitRequestStatus.PENDING); @@ -175,12 +186,12 @@ public class JitServiceImpl implements JitService { actionEnabled = false; } // inform reviewer on slack that request is approved and remove action buttons - updateReviewerDMOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); // send group message to common channel with details on pending and approved reviewers updateChannelOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); - updateRequestorDMOnSlack(jitRequest, pendingReviewers, + updateRequestorDmOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers, actionEnabled); jitRequestRepository.save(jitRequest); @@ -215,8 +226,8 @@ public class JitServiceImpl implements JitService { jitApproval.setAction(JitRequestStatus.REJECTED); jitRequest.setStatus(JitRequestStatus.REJECTED); - updateReviewerDMOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); - updateRequestorDMOnSlack(jitRequest, pendingReviewers, + updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + updateRequestorDmOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers, false); updateChannelOnSlack(jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); @@ -240,12 +251,12 @@ public class JitServiceImpl implements JitService { jitApproval.setReviewedAt(LocalDateTime.now()); jitApproval.setAction(JitRequestStatus.CANCELLED); jitApprovalsRepository.save(jitApproval); - updateReviewerDMOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, + updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); } updateChannelOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); - updateRequestorDMOnSlack(jitRequest, new ArrayList<>(), + updateRequestorDmOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), false); jitRequestRepository.save(jitRequest); return 0; @@ -273,17 +284,22 @@ public class JitServiceImpl implements JitService { JitRequest jitRequest = mapToJitRequest(jitRequestDto); // Determine the reviewers based on REQUEST - List reviewers = authUtil.getReviewers(jitRequestDto); + List reviewers = authUtil.getReviewers(jitRequestDto) + .stream() + .distinct() + .filter(user -> !user.getEmail().equals(jitRequest.getRequestedFor().getEmail())) + .collect(Collectors.toList()); log.info("Requesting review from {}", reviewers); + if (reviewers.size() == 0) { + // no reviewers found, inform user + updateRequestorNoReviewersDmOnSlack(jitRequest); + return true; + } List jitApprovals = new ArrayList<>(); List pendingReviewers = new ArrayList<>(); String messageTimestamp = ""; for (User reviewer : reviewers) { - if (reviewer.getEmail().equals(jitRequest.getRequestedFor().getEmail())) { - // User cannot review his/her own request - continue; - } JitApproval jitApproval = new JitApproval(jitRequest, reviewer, JitRequestStatus.PENDING); jitApprovals.add(jitApproval); @@ -295,7 +311,7 @@ public class JitServiceImpl implements JitService { // send personal message to user with details on pending and approved reviewers JitRequest jitRequestWithId = jitRequestRepository.save(jitRequest); - updateRequestorDMOnSlack(jitRequestWithId, pendingReviewers, + updateRequestorDmOnSlack(jitRequestWithId, pendingReviewers, new ArrayList<>(), new ArrayList<>(), true); // send group message to common channel with details on pending and approved reviewers @@ -306,7 +322,7 @@ public class JitServiceImpl implements JitService { JitRequest finalJitRequest = jitRequest; jitApprovalsWithId.stream().forEach(jitApproval -> { try { - updateReviewerDMOnSlack(jitApproval.getReviewer(), + updateReviewerDmOnSlack(jitApproval.getReviewer(), finalJitRequest, jitApproval, true); } catch (IOException e) { throw new RuntimeException(e); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 4ee4e26d..592cc8a9 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -11,6 +11,7 @@ import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; import com.navi.infra.portal.v2.role.RoleService; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; @@ -80,12 +81,16 @@ public class AuthUtil { public List getReviewers(JitRequestDto jitRequestDto) { // Determine the reviewers based on REQUEST + List reviewers = new ArrayList<>(); Role reviewerRole = new Role(String.join("_", jitRequestDto.getTeam(), jitRequestDto.getEnvironment().toString().toLowerCase(), JITREVIEWER.toString())); - List reviewers = userService.getUsersWithRole(reviewerRole.getName()); + List environmentSpecificReviewers = userService.getUsersWithRole(reviewerRole.getName()); reviewerRole = new Role( String.join("_", jitRequestDto.getTeam(), "ALL", JITREVIEWER.toString())); - reviewers.addAll(userService.getUsersWithRole(reviewerRole.getName())); + List allEnvironmentReviewers = userService.getUsersWithRole(reviewerRole.getName()); + reviewers.addAll(environmentSpecificReviewers); + reviewers.addAll(allEnvironmentReviewers); + // TODO Add exception in case no reviewers found // TODO reduce number of userService calls thereby reducing DB calls return reviewers; } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index 325b4fc7..7bfae1d5 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -20,7 +20,7 @@ public class SlackBotUtil { private static final String SlackYellow = "#f2c744"; - public SlackBotAttachment getReviewerDM( + public SlackBotAttachment getReviewerDm( String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled ) { ArrayList blocks = new ArrayList<>(); @@ -65,7 +65,7 @@ public class SlackBotUtil { return new SlackBotAttachment(SlackYellow, blocks); } - public SlackBotAttachment getRequestorDM( + public SlackBotAttachment getRequestorDm( String userEmail, JitRequest jitRequest, Boolean actionEnabled, @@ -83,16 +83,16 @@ public class SlackBotUtil { SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( SlackMessageBlockType.SECTION, reviewRequestText, null); - SlackMessageText closeText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, - "Close"); - SlackMessageElement closeButton = new SlackMessageElement(SlackElementType.BUTTON, - closeText, SlackElementStyle.DANGER, jitRequest.getId().toString(), "actionClose"); - ArrayList blocks = new ArrayList<>(); blocks.add(reviewRequestSection); if (actionEnabled) { ArrayList elements = new ArrayList<>(); + + SlackMessageText closeText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, + "Close"); + SlackMessageElement closeButton = new SlackMessageElement(SlackElementType.BUTTON, + closeText, SlackElementStyle.DANGER, jitRequest.getId().toString(), "actionClose"); elements.add(closeButton); SlackBotMessageBlock reviewRequestAction = new SlackBotMessageBlock( SlackMessageBlockType.ACTIONS, null, elements); @@ -102,6 +102,24 @@ public class SlackBotUtil { return new SlackBotAttachment(SlackYellow, blocks); } + public SlackBotAttachment getRequestorNoReviewerDm( + JitRequest jitRequest + ) { + SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, + String.format( + "No Reviewers present for team: %s. Kindly get notify team to have reviewers. " + + "Contact Cloud Platform oncall if issue persists", + jitRequest.getTeam().getName())); + + SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( + SlackMessageBlockType.SECTION, reviewRequestText, null); + + ArrayList blocks = new ArrayList<>(); + blocks.add(reviewRequestSection); + + return new SlackBotAttachment(SlackYellow, blocks); + } + public SlackBotAttachment getChannelMessage( JitRequest jitRequest, String email, diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java index e439f0bc..4ff341c9 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java @@ -29,7 +29,7 @@ public class SlackBotUtilTest { jitApproval.setId(1L); SlackBotAttachment result = - slackBotUtil.getReviewerDM(userEmail, jitRequest, jitApproval, true); + slackBotUtil.getReviewerDm(userEmail, jitRequest, jitApproval, true); Assertions.assertEquals(2, result.getBlocks().size()); // Section + action block } @@ -38,7 +38,7 @@ public class SlackBotUtilTest { public void testPersonalMessage_ActionEnabled() { jitRequest.setId(2L); SlackBotAttachment result = - slackBotUtil.getRequestorDM(userEmail, jitRequest, true, + slackBotUtil.getRequestorDm(userEmail, jitRequest, true, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), "PENDING"); Assertions.assertEquals(2, result.getBlocks().size()); // Section + action block From 15b3851a2d3de52ab8c679aeabbe0a58e577a612 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 28 Mar 2024 18:47:23 +0530 Subject: [PATCH 017/108] INFRA-2219 | Harinder | Updating application.properties files --- src/main/resources/application.properties | 2 +- src/test/resources/application.properties | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 26298a39..4313801b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -73,6 +73,6 @@ aws.profile=${AWS_PROFILE:default} spring.mvc.async.request-timeout=1800000 jit.number_of_prod_approvals=2 jit.number_of_nonprod_approvals=1 -slackbot.token=xoxb-6761910733-191044292705-1 +slackbot.token=${SLACK_BOT_TOKEN:xoxb-6761910733-191044292705-1} jit.dag.id=${JIT_DAG_ID} jit.slack.common.channel.id=C06NDTBFA1G \ No newline at end of file diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index db0c9ee8..5303953a 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -59,7 +59,6 @@ kubernetes.security-group.id.fetch.fixed-backoff.interval=${SECURITY_GROUP_ID_FE kubernetes.security-group.id.fetch.fixed-backoff.max-attempts=${SECURITY_GROUP_ID_FETCH_FIXED_BACKOFF_MAX_ATTEMPTS:5} extraResource.list=database,docdb,elasticCache,aws_access,dynamodb,s3_buckets,deployment airflow.url=${AIRFLOW_URL:http://localhost:9090} -jit.airflow.url=${JIT_AIRFLOW_URL:http://localhost:9090} airflow.token=${AIRFLOW_AUTH_TOKEN:something} service-dump.dag.id=${SERVICE_DUMP_DAG_ID:kubectl_get_pod} jit.dag.id=${JIT_DAG_ID:jit_dag} From 4d423a84e02f52929a288171b52688eee7f6a951 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 28 Mar 2024 18:58:05 +0530 Subject: [PATCH 018/108] INFRA-2219 | Harinder | Updating files as per reviewdog --- .../infra/portal/v2/jit/utils/AuthUtil.java | 3 ++- .../v2/jit/service/JitServiceImplTest.java | 18 ++++++++++++------ .../portal/v2/jit/utils/AuthUtilTest.java | 4 ++-- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 592cc8a9..7657d89e 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -84,7 +84,8 @@ public class AuthUtil { List reviewers = new ArrayList<>(); Role reviewerRole = new Role(String.join("_", jitRequestDto.getTeam(), jitRequestDto.getEnvironment().toString().toLowerCase(), JITREVIEWER.toString())); - List environmentSpecificReviewers = userService.getUsersWithRole(reviewerRole.getName()); + List environmentSpecificReviewers = userService.getUsersWithRole( + reviewerRole.getName()); reviewerRole = new Role( String.join("_", jitRequestDto.getTeam(), "ALL", JITREVIEWER.toString())); List allEnvironmentReviewers = userService.getUsersWithRole(reviewerRole.getName()); diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java index 2ffb201d..e51f4450 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -54,10 +54,13 @@ public class JitServiceImplTest { @Test - public void TestCreateJitRequest() throws IOException { + public void testCreateJitRequest() throws IOException { // Arrange requestedFor.setEmail("alpha@one.com"); requestedBy.setEmail("beta@two.com"); + when(userService.findUserByEmail("alpha@one.com")).thenReturn(requestedFor); + when(userService.findUserByEmail("beta@two.com")).thenReturn(requestedBy); + JitRequest jitRequest = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, 1L, LocalDateTime.now()); @@ -65,12 +68,14 @@ public class JitServiceImplTest { new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, 1L, LocalDateTime.now()); jitRequestWithId.setId(1L); + when(jitRequestRepository.save(any())).thenReturn(jitRequestWithId); User reviewerOne = new User(); reviewerOne.setEmail("charlie@three.com"); User reviewerTwo = new User(); reviewerTwo.setEmail("delte@four.com"); List reviewers = List.of(reviewerOne, reviewerTwo); + when(authUtil.getReviewers(jitRequestDto)).thenReturn(reviewers); JitApproval jitApprovalOne = new JitApproval(jitRequest, reviewerOne, JitRequestStatus.PENDING); @@ -85,12 +90,13 @@ public class JitServiceImplTest { List jitApprovals = List.of(jitApprovalOne, jitApprovalTwo); List jitApprovalsWithId = List.of(jitApprovalOneWithId, jitApprovalTwoWithId); - // Mock - when(userService.findUserByEmail("alpha@one.com")).thenReturn(requestedFor); - when(userService.findUserByEmail("beta@two.com")).thenReturn(requestedBy); +// when(userService.findUserByEmail("alpha@one.com")).thenReturn(requestedFor); +// when(userService.findUserByEmail("beta@two.com")).thenReturn(requestedBy); when(teamService.findByName("Infra")).thenReturn(new Team("Infra")); - when(authUtil.getReviewers(jitRequestDto)).thenReturn(reviewers); - when(jitRequestRepository.save(any())).thenReturn(jitRequestWithId); + + +// when(authUtil.getReviewers(jitRequestDto)).thenReturn(reviewers); +// when(jitRequestRepository.save(any())).thenReturn(jitRequestWithId); when(userService.getSlackId(jitRequest.getRequestedFor().getEmail())).thenReturn("U12314"); when(slackBotClient.postMessage(any(), any())).thenReturn("2341419824719"); when(jitApprovalsRepository.saveAll(jitApprovals)).thenReturn(jitApprovalsWithId); diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java index 11d120d4..2dc7b0a1 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -72,7 +72,7 @@ public class AuthUtilTest { } @Test - @DisplayName("Should be able to check if the request has enough approvals as per environment PROD") + @DisplayName("Should be able to check if required approvals are done. Environment PROD") public void testCheckRequiredApprovalsProd() { JitRequest jitRequest = new JitRequest(); jitRequest.setEnvironment(Environment.PROD); @@ -88,7 +88,7 @@ public class AuthUtilTest { } @Test - @DisplayName("Should be able to check if the request has enough approvals as per environment NONPROD") + @DisplayName("Should be able to check if required approvals are done. Environment NONPROD") public void testCheckRequiredApprovalsNonprod() { JitRequest jitRequest = new JitRequest(); jitRequest.setEnvironment(Environment.DEV); From e585a348a3f197996e6b8ba3373212ca93431d6e Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 28 Mar 2024 21:05:29 +0530 Subject: [PATCH 019/108] INFRA-2219 | Harinder | Enhancing slackbotclient's intialization --- .../portal/v2/slackbotclient/SlackBotClient.java | 8 +++++--- .../v2/slackbotclient/SlackConfiguration.java | 14 ++++++++++++++ src/main/resources/application.properties | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackConfiguration.java diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java index b4993eda..e967ec07 100644 --- a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java @@ -2,6 +2,7 @@ package com.navi.infra.portal.v2.slackbotclient; import com.fasterxml.jackson.databind.ObjectMapper; import com.slack.api.Slack; +import com.slack.api.methods.MethodsClient; import com.slack.api.methods.SlackApiException; import com.slack.api.model.User; import java.io.IOException; @@ -10,6 +11,7 @@ import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -24,9 +26,11 @@ public class SlackBotClient { @Value("${slackbot.token}") private String slackBotToken; + @Autowired + private MethodsClient client; + public Map fetchAndProcessSlackUsers() throws IOException { Map userSlackIdMap = new HashMap<>(); - var client = Slack.getInstance().methods(); // Slack client reference: https://api.slack.com/methods/users.list/code try { @@ -52,7 +56,6 @@ public class SlackBotClient { public String postMessage(String channelId, SlackBotAttachment slackBotAttachment) throws IOException { - var client = Slack.getInstance().methods(); // Slack client reference: https://api.slack.com/methods/chat.postMessage/code try { ObjectMapper objectMapper = new ObjectMapper(); @@ -72,7 +75,6 @@ public class SlackBotClient { public String updateMessage(String channelId, SlackBotAttachment slackBotAttachment, String ts) throws IOException { - var client = Slack.getInstance().methods(); try { ObjectMapper objectMapper = new ObjectMapper(); String textJson = "[" + objectMapper.writeValueAsString(slackBotAttachment) + "]"; diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackConfiguration.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackConfiguration.java new file mode 100644 index 00000000..d24fd298 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackConfiguration.java @@ -0,0 +1,14 @@ +package com.navi.infra.portal.v2.slackbotclient; + +import com.slack.api.Slack; +import com.slack.api.methods.MethodsClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SlackConfiguration { + @Bean + public MethodsClient client() { + return Slack.getInstance().methods(); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4313801b..71df9af8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -73,6 +73,6 @@ aws.profile=${AWS_PROFILE:default} spring.mvc.async.request-timeout=1800000 jit.number_of_prod_approvals=2 jit.number_of_nonprod_approvals=1 -slackbot.token=${SLACK_BOT_TOKEN:xoxb-6761910733-191044292705-1} +slackbot.token=${SLACK_BOT_TOKEN} jit.dag.id=${JIT_DAG_ID} jit.slack.common.channel.id=C06NDTBFA1G \ No newline at end of file From b1fefac0db4360a070fa94815f3de83a16ed9118 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 29 Mar 2024 15:56:58 +0530 Subject: [PATCH 020/108] INFRA-2219 | Harinder | Removing getstatus() from JitServiceImpl, UserService and UserRepository related changes from review, reviewdog linting updates, added PORTAL_JITVIEWER and PORTAL_JITREVIEWER, updated authUtil isAuthorized to work properly --- .../portal/repository/UserRepository.java | 11 ------ .../portal/service/user/UserService.java | 36 +++++++++++------- .../repository/JitApprovalsRepository.java | 3 +- .../portal/v2/jit/service/JitServiceImpl.java | 38 +++++++++---------- .../infra/portal/v2/jit/utils/AuthUtil.java | 14 ++++--- .../V1.73__Add_jit_roles_privileges.sql | 9 ++++- .../v2/jit/service/JitServiceImplTest.java | 17 ++------- .../portal/v2/jit/utils/AuthUtilTest.java | 2 - 8 files changed, 61 insertions(+), 69 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/repository/UserRepository.java b/src/main/java/com/navi/infra/portal/repository/UserRepository.java index e65ad07a..6e71894a 100644 --- a/src/main/java/com/navi/infra/portal/repository/UserRepository.java +++ b/src/main/java/com/navi/infra/portal/repository/UserRepository.java @@ -13,9 +13,6 @@ public interface UserRepository extends JpaRepository { @Query("SELECT u FROM User u WHERE lower(u.email) = :email") Optional findByEmail(String email); - @Query("SELECT u FROM User u WHERE lower(u.email) = :email") - User findUserByEmail(String email); - @Query("SELECT u.id FROM User u WHERE lower(u.email) = :email") Long findIdByEmail(String email); @@ -29,12 +26,4 @@ public interface UserRepository extends JpaRepository { @Query(value = "SELECT ur.role_id FROM users_roles ur WHERE ur.user_id = :userId)", nativeQuery = true) List findAllRolesOfUser(Long userId); - - @Query(value = "SELECT u FROM users u WHERE u.id IN = :roleId)", nativeQuery = true) - User findUsersByRoleName(Long roleId); - - - @Query(value = "SELECT u.slack_id FROM users u WHERE lower(u.email) = :email", - nativeQuery = true) - Optional findSlackId(String email); } diff --git a/src/main/java/com/navi/infra/portal/service/user/UserService.java b/src/main/java/com/navi/infra/portal/service/user/UserService.java index 90d6dce3..092ea0c0 100644 --- a/src/main/java/com/navi/infra/portal/service/user/UserService.java +++ b/src/main/java/com/navi/infra/portal/service/user/UserService.java @@ -311,7 +311,11 @@ public class UserService { } public User findUserByEmail(String email) { - return userRepository.findUserByEmail(email); + Optional optionalUser = userRepository.findByEmail(email); + if (optionalUser.isPresent()) { + return optionalUser.get(); + } + throw new UsernameNotFoundException(email + " not found"); } public List getUsersWithRole(String roleName) { @@ -324,20 +328,24 @@ public class UserService { Long id = userRepository.findIdByEmail(email); return userRepository.findAllRolesOfUser(id); } + + private void syncUserEmailAndSlackId() throws IOException { + var users = userRepository.findAll(); + Map emailSlackIdMapping = slackBotClient.fetchAndProcessSlackUsers(); + users.forEach(user -> { + if (user.getSlackId() == null || user.getSlackId().isEmpty()) { + user.setSlackId(emailSlackIdMapping.get(user.getEmail())); + } + }); + userRepository.saveAll(users); + } - public String getSlackId(String email) throws IOException { - Optional slackId = userRepository.findSlackId(email); - if (!slackId.isPresent()) { - var users = userRepository.findAll(); - Map emailSlackIdMapping = slackBotClient.fetchAndProcessSlackUsers(); - users.forEach(user -> { - if (user.getSlackId() == null || user.getSlackId().isEmpty()) { - user.setSlackId(emailSlackIdMapping.get(user.getEmail())); - } - }); - userRepository.saveAll(users); - return getSlackId(email); + public String getUsersSlackId(User user) throws IOException { + String slackId = user.getSlackId(); + if (slackId == null || slackId.isEmpty()){ + syncUserEmailAndSlackId(); + return user.getSlackId(); } - return slackId.get(); + return slackId; } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java index 5c8e482b..0a1bbbc3 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java @@ -17,7 +17,8 @@ public interface JitApprovalsRepository extends JpaRepository nativeQuery = true) List findAllReviewsByJitId(Long jitId); - @Query(value = "SELECT COUNT(ja.reviewer_id) FROM jit_approvals ja WHERE ja.jit_id = :jitId AND ja.action = 'APPROVED'", + @Query(value = "SELECT COUNT(ja.reviewer_id) FROM jit_approvals ja WHERE " + + "ja.jit_id = :jitId AND ja.action = 'APPROVED'", nativeQuery = true) Long findApprovedRequestsCount(Long jitId); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index ee7d18bd..28e9fbc1 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -64,7 +64,7 @@ public class JitServiceImpl implements JitService { SlackBotAttachment reviewMessage = slackBotUtil.getReviewerDm( jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled); String messageTimestamp = slackBotClient.postMessage( - userService.getSlackId(reviewer.getEmail()), reviewMessage); + userService.getUsersSlackId(reviewer), reviewMessage); jitApproval.setReviewerSlackMessageTimestamp(messageTimestamp); jitApprovalsRepository.save(jitApproval); @@ -81,15 +81,16 @@ public class JitServiceImpl implements JitService { SlackBotAttachment personalMessage = slackBotUtil.getRequestorDm( jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingReviewers, approvedReviewers, rejectedReviewers, jitRequest.getStatus().toString()); + String messageTimestamp = slackBotClient.postMessage( - userService.getSlackId(jitRequest.getRequestedFor().getEmail()), personalMessage); + userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); jitRequest.setRequestorSlackMessageTimestamp(messageTimestamp); } private void updateRequestorNoReviewersDmOnSlack(JitRequest jitRequest) throws IOException { SlackBotAttachment personalMessage = slackBotUtil.getRequestorNoReviewerDm(jitRequest); slackBotClient.postMessage( - userService.getSlackId(jitRequest.getRequestedFor().getEmail()), personalMessage); + userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); } private void updateChannelOnSlack( @@ -106,6 +107,15 @@ public class JitServiceImpl implements JitService { jitRequest.setChannelSlackMessageTimestamp(messageTimestamp); } + private void validateGrantTime(JitRequest jitRequest) { + jitRequest.setGrantAt(jitRequest.getGrantAt() == null + ? LocalDateTime.now() + : jitRequest.getGrantAt()); + jitRequest.setGrantAt(jitRequest.getGrantAt().isBefore(LocalDateTime.now()) + ? LocalDateTime.now() + : jitRequest.getGrantAt()); + } + private Integer processJitRequest( String reviewerEmail, Long requestId, @@ -117,17 +127,16 @@ public class JitServiceImpl implements JitService { if (optionalJitApproval.isPresent()) { JitApproval jitApproval = optionalJitApproval.get(); JitRequest jitRequest = jitApproval.getJitRequest(); - if (jitApproval.getReviewedAt() != null || !jitRequest.getStatus() - .equals(JitRequestStatus.PENDING)) { + if (jitApproval.getReviewedAt() != null + || !jitRequest.getStatus().equals(JitRequestStatus.PENDING)) { log.error("Request already reviewed"); return -1; } jitApproval.setReviewedAt(LocalDateTime.now()); if (!reviewerEmail.equals(jitApproval.getReviewer().getEmail()) - && !authUtil.isAuthorized( - reviewerEmail, jitRequest) && reviewerEmail.equals( - jitRequest.getRequestedFor().getEmail())) { + && !authUtil.isAuthorized(reviewerEmail, jitRequest) + && reviewerEmail.equals(jitRequest.getRequestedFor().getEmail())) { log.error("User {} not allowed to perform action", reviewerEmail); return -1; } @@ -165,8 +174,6 @@ public class JitServiceImpl implements JitService { ) throws IOException { try { - approvedReviewers.add(reviewerEmail); - boolean actionEnabled = true; if (authUtil.checkRequiredApprovals(jitRequest)) { // if required number of approvals are met, @@ -203,15 +210,6 @@ public class JitServiceImpl implements JitService { } } - private void validateGrantTime(JitRequest jitRequest) { - jitRequest.setGrantAt(jitRequest.getGrantAt() == null - ? LocalDateTime.now() - : jitRequest.getGrantAt()); - jitRequest.setGrantAt(jitRequest.getGrantAt().isBefore(LocalDateTime.now()) - ? LocalDateTime.now() - : jitRequest.getGrantAt()); - } - private Integer jitRejectedFlow( String reviewerEmail, JitApproval jitApproval, @@ -221,8 +219,6 @@ public class JitServiceImpl implements JitService { List rejectedReviewers ) { try { - rejectedReviewers.add(reviewerEmail); - jitApproval.setAction(JitRequestStatus.REJECTED); jitRequest.setStatus(JitRequestStatus.REJECTED); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 7657d89e..724d7ce7 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -34,14 +34,16 @@ public class AuthUtil { private Long nonprodJitApprovalsCount; public boolean isAuthorized(String userEmail, JitRequest jitRequest) { - List userRolesId = userService.listAllRolesOfUser(userEmail); - List userRoles = roleService.listAllAuthorities(userRolesId); - + User user = userService.findUserByEmail(userEmail); + List userRoles = user.getRoles().stream().map(Role::getName) + .collect(Collectors.toList()); return userRoles.stream() .filter(role -> role.contains(JITREVIEWER.toString()) - && role.contains(jitRequest.getTeam().getName())) - .anyMatch(role -> role.contains(jitRequest.getEnvironment().toString()) - || role.contains("ALL")); + && (role.contains(jitRequest.getTeam().getName())) + || role.contains("PORTAL")) + .anyMatch(role -> role.contains(jitRequest.getEnvironment().type) + || role.contains("ALL") + || role.contains("PORTAL")); } public List getReviewersByAction( diff --git a/src/main/resources/db/migration/V1.73__Add_jit_roles_privileges.sql b/src/main/resources/db/migration/V1.73__Add_jit_roles_privileges.sql index 4d8ed085..009371a2 100644 --- a/src/main/resources/db/migration/V1.73__Add_jit_roles_privileges.sql +++ b/src/main/resources/db/migration/V1.73__Add_jit_roles_privileges.sql @@ -2178,4 +2178,11 @@ INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:UnderwritingAndFraudDetection:.*:.*:read'), (now(), now(), 'jit:UnderwritingAndFraudDetection:.*:.*:review'); INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'UnderwritingAndFraudDetection_ALL_JITVIEWER'), (now(), now(), 'UnderwritingAndFraudDetection_ALL_JITREVIEWER'); INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_ALL_JITVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:.*:.*:read' ); -INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:.*:.*:read', 'jit:UnderwritingAndFraudDetection:.*:.*:review'); \ No newline at end of file +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'UnderwritingAndFraudDetection_ALL_JITREVIEWER' AND privilege.name IN ( 'jit:UnderwritingAndFraudDetection:.*:.*:read', 'jit:UnderwritingAndFraudDetection:.*:.*:review'); + + +INSERT INTO privilege (created_at, updated_at, name) VALUES (now(), now(), 'jit:.*:.*:.*:read'), (now(), now(), 'jit:.*:.*:.*:review'); +INSERT INTO role (created_at, updated_at, name) VALUES (now(), now(), 'PORTAL_JITVIEWER'), (now(), now(), 'PORTAL_JITREVIEWER'); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PORTAL_JITVIEWER' AND privilege.name IN ( 'jit:.*:.*:.*:read' ); +INSERT INTO roles_privileges (role_id, privilege_id) SELECT role.id AS role_id, privilege.id AS privilege_id FROM role, privilege WHERE role.name = 'PORTAL_JITREVIEWER' AND privilege.name IN ( 'jit:.*:.*:.*:read', 'jit:.*:.*:.*:review'); + diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java index e51f4450..9abc665e 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -61,9 +61,6 @@ public class JitServiceImplTest { when(userService.findUserByEmail("alpha@one.com")).thenReturn(requestedFor); when(userService.findUserByEmail("beta@two.com")).thenReturn(requestedBy); - JitRequest jitRequest = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, - new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, - 1L, LocalDateTime.now()); JitRequest jitRequestWithId = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, 1L, LocalDateTime.now()); @@ -77,6 +74,9 @@ public class JitServiceImplTest { List reviewers = List.of(reviewerOne, reviewerTwo); when(authUtil.getReviewers(jitRequestDto)).thenReturn(reviewers); + JitRequest jitRequest = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, + new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, + 1L, LocalDateTime.now()); JitApproval jitApprovalOne = new JitApproval(jitRequest, reviewerOne, JitRequestStatus.PENDING); JitApproval jitApprovalOneWithId = jitApprovalOne; @@ -90,22 +90,13 @@ public class JitServiceImplTest { List jitApprovals = List.of(jitApprovalOne, jitApprovalTwo); List jitApprovalsWithId = List.of(jitApprovalOneWithId, jitApprovalTwoWithId); -// when(userService.findUserByEmail("alpha@one.com")).thenReturn(requestedFor); -// when(userService.findUserByEmail("beta@two.com")).thenReturn(requestedBy); when(teamService.findByName("Infra")).thenReturn(new Team("Infra")); - - -// when(authUtil.getReviewers(jitRequestDto)).thenReturn(reviewers); -// when(jitRequestRepository.save(any())).thenReturn(jitRequestWithId); - when(userService.getSlackId(jitRequest.getRequestedFor().getEmail())).thenReturn("U12314"); + when(userService.getUsersSlackId(jitRequest.getRequestedFor())).thenReturn("U12314"); when(slackBotClient.postMessage(any(), any())).thenReturn("2341419824719"); when(jitApprovalsRepository.saveAll(jitApprovals)).thenReturn(jitApprovalsWithId); when(jitRequestRepository.save(jitRequest)).thenReturn(jitRequest); - // Act Boolean result = jitServiceImpl.createJitRequest(jitRequestDto); - - // Assert Assertions.assertTrue(result); } } diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java index 2dc7b0a1..7273effd 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -122,10 +122,8 @@ public class AuthUtilTest { when(userService.getUsersWithRole("Infra_ALL_JITREVIEWER")) .thenReturn(allReviewers); - // Execution List result = authUtil.getReviewers(mockRequestDto); - // Assertions Assertions.assertEquals(2, result.size()); Assertions.assertTrue(result.contains(reviewer1)); Assertions.assertTrue(result.contains(reviewer2)); From c90fea5e696dc13cd3c04cae4ac7d8d6c1936094 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 29 Mar 2024 18:46:03 +0530 Subject: [PATCH 021/108] INFRA-2219 | Harinder | Updating Jit controller and service to use exceptions. Introducing new colors for Slack messages --- .../portal/service/user/UserService.java | 4 +- .../v2/jit/controller/JitController.java | 43 +++++---- .../portal/v2/jit/service/JitService.java | 10 +- .../portal/v2/jit/service/JitServiceImpl.java | 94 ++++++++++--------- .../portal/v2/jit/utils/SlackBotUtil.java | 24 +++-- .../infra/portal/v2/jit/utils/SlackColor.java | 14 +++ .../v2/jit/service/JitServiceImplTest.java | 3 +- .../portal/v2/jit/utils/SlackBotUtilTest.java | 6 +- 8 files changed, 114 insertions(+), 84 deletions(-) create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/utils/SlackColor.java diff --git a/src/main/java/com/navi/infra/portal/service/user/UserService.java b/src/main/java/com/navi/infra/portal/service/user/UserService.java index 092ea0c0..9e0e8e5b 100644 --- a/src/main/java/com/navi/infra/portal/service/user/UserService.java +++ b/src/main/java/com/navi/infra/portal/service/user/UserService.java @@ -328,7 +328,7 @@ public class UserService { Long id = userRepository.findIdByEmail(email); return userRepository.findAllRolesOfUser(id); } - + private void syncUserEmailAndSlackId() throws IOException { var users = userRepository.findAll(); Map emailSlackIdMapping = slackBotClient.fetchAndProcessSlackUsers(); @@ -342,7 +342,7 @@ public class UserService { public String getUsersSlackId(User user) throws IOException { String slackId = user.getSlackId(); - if (slackId == null || slackId.isEmpty()){ + if (slackId == null || slackId.isEmpty()) { syncUserEmailAndSlackId(); return user.getSlackId(); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java index 8e7e161b..d972616d 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java @@ -5,6 +5,7 @@ import com.navi.infra.portal.v2.jit.dto.JitResponseDto; import com.navi.infra.portal.v2.jit.dto.JitUserDto; import com.navi.infra.portal.v2.jit.service.JitService; import java.io.IOException; +import java.net.ConnectException; import javax.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -30,13 +31,14 @@ public class JitController { @PostMapping public ResponseEntity createJitRequest( - @Valid @RequestBody JitRequestDto jitRequestDto) { + @Valid @RequestBody JitRequestDto jitRequestDto + ) { try { - return jitService.createJitRequest(jitRequestDto) - ? ResponseEntity.status(HttpStatus.CREATED).build() - : ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); - } catch (IllegalArgumentException | IOException ex) { - log.error(ex.getMessage()); + jitService.createJitRequest(jitRequestDto); + return ResponseEntity.status(HttpStatus.CREATED).build(); + } catch (IllegalArgumentException | IllegalStateException ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); + } catch (IOException ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } @@ -47,11 +49,13 @@ public class JitController { @PathVariable Long reviewId ) { try { - return jitService.approveJitRequest(approver.getUser(), reviewId) == -1 - ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() - : ResponseEntity.status(HttpStatus.OK).build(); + jitService.approveJitRequest(approver.getUser(), reviewId); + return ResponseEntity.status(HttpStatus.OK).build(); + } catch (IllegalStateException | IllegalAccessException ex) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } catch (ConnectException ex) { + return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build(); } catch (Exception ex) { - log.error(ex.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } @@ -62,11 +66,13 @@ public class JitController { @PathVariable Long reviewId ) { try { - return jitService.rejectJitRequest(rejecter.getUser(), reviewId) == -1 - ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() - : ResponseEntity.status(HttpStatus.OK).build(); + jitService.rejectJitRequest(rejecter.getUser(), reviewId); + return ResponseEntity.status(HttpStatus.OK).build(); + } catch (IllegalStateException | IllegalAccessException ex) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } catch (ConnectException ex) { + return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build(); } catch (Exception ex) { - log.error(ex.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } @@ -77,12 +83,11 @@ public class JitController { @PathVariable Long id ) { try { - JitResponseDto jitResponse = jitService.closeRequest(closer.getUser(), id); - return jitResponse.getId() == -1 - ? ResponseEntity.status(HttpStatus.UNAUTHORIZED).build() - : ResponseEntity.status(HttpStatus.OK).build(); + jitService.closeRequest(closer.getUser(), id); + return ResponseEntity.status(HttpStatus.OK).build(); + } catch (IllegalStateException | IllegalAccessException ex) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } catch (Exception ex) { - log.error(ex.getMessage()); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java index cfe966f3..d4142522 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitService.java @@ -6,11 +6,13 @@ import java.io.IOException; public interface JitService { - Boolean createJitRequest(JitRequestDto jitRequestDto) throws IOException; + void createJitRequest(JitRequestDto jitRequestDto) throws IOException; - Integer approveJitRequest(String approver, Long requestId) throws IOException; + void approveJitRequest(String approver, Long requestId) + throws IOException, IllegalAccessException; - Integer rejectJitRequest(String rejecter, Long requestId) throws IOException; + void rejectJitRequest(String rejecter, Long requestId) + throws IOException, IllegalAccessException; - JitResponseDto closeRequest(String closer, Long requestId); + void closeRequest(String closer, Long requestId) throws IllegalAccessException; } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 28e9fbc1..eaeba849 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -4,7 +4,6 @@ import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; import com.navi.infra.portal.v2.client.airflow.AirflowClient; import com.navi.infra.portal.v2.jit.dto.JitRequestDto; -import com.navi.infra.portal.v2.jit.dto.JitResponseDto; import com.navi.infra.portal.v2.jit.entity.JitApproval; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; @@ -12,12 +11,14 @@ import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; import com.navi.infra.portal.v2.jit.repository.JitRequestsRepository; import com.navi.infra.portal.v2.jit.utils.AuthUtil; import com.navi.infra.portal.v2.jit.utils.SlackBotUtil; +import com.navi.infra.portal.v2.jit.utils.SlackColor; import com.navi.infra.portal.v2.privilege.ResourceType; import com.navi.infra.portal.v2.role.RoleService; import com.navi.infra.portal.v2.slackbotclient.SlackBotAttachment; import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; import com.navi.infra.portal.v2.team.TeamService; import java.io.IOException; +import java.net.ConnectException; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -58,11 +59,12 @@ public class JitServiceImpl implements JitService { User reviewer, JitRequest jitRequest, JitApproval jitApproval, - boolean actionEnabled + boolean actionEnabled, + SlackColor color ) throws IOException { SlackBotAttachment reviewMessage = slackBotUtil.getReviewerDm( - jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled); + jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled, color); String messageTimestamp = slackBotClient.postMessage( userService.getUsersSlackId(reviewer), reviewMessage); jitApproval.setReviewerSlackMessageTimestamp(messageTimestamp); @@ -75,12 +77,13 @@ public class JitServiceImpl implements JitService { List pendingReviewers, List approvedReviewers, List rejectedReviewers, - boolean actionEnabled + boolean actionEnabled, + SlackColor color ) throws IOException { SlackBotAttachment personalMessage = slackBotUtil.getRequestorDm( jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingReviewers, - approvedReviewers, rejectedReviewers, jitRequest.getStatus().toString()); + approvedReviewers, rejectedReviewers, jitRequest.getStatus().toString(), color); String messageTimestamp = slackBotClient.postMessage( userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); @@ -97,12 +100,13 @@ public class JitServiceImpl implements JitService { JitRequest jitRequest, List pendingReviewers, List approvedReviewers, - List rejectedReviewers + List rejectedReviewers, + SlackColor color ) throws IOException { SlackBotAttachment commonChannelMessage = slackBotUtil.getChannelMessage(jitRequest, jitRequest.getRequestedFor().getEmail(), pendingReviewers, approvedReviewers, - rejectedReviewers); + rejectedReviewers, color); String messageTimestamp = slackBotClient.postMessage(commonChannelId, commonChannelMessage); jitRequest.setChannelSlackMessageTimestamp(messageTimestamp); } @@ -116,12 +120,12 @@ public class JitServiceImpl implements JitService { : jitRequest.getGrantAt()); } - private Integer processJitRequest( + private void processJitRequest( String reviewerEmail, Long requestId, JitRequestStatus jitRequestStatus, JitFlowFunction flowFunction - ) throws IOException { + ) throws IOException, IllegalAccessException { Optional optionalJitApproval = jitApprovalsRepository.findById(requestId); if (optionalJitApproval.isPresent()) { @@ -130,7 +134,7 @@ public class JitServiceImpl implements JitService { if (jitApproval.getReviewedAt() != null || !jitRequest.getStatus().equals(JitRequestStatus.PENDING)) { log.error("Request already reviewed"); - return -1; + throw new IllegalStateException("Request already reviewed"); } jitApproval.setReviewedAt(LocalDateTime.now()); @@ -138,7 +142,7 @@ public class JitServiceImpl implements JitService { && !authUtil.isAuthorized(reviewerEmail, jitRequest) && reviewerEmail.equals(jitRequest.getRequestedFor().getEmail())) { log.error("User {} not allowed to perform action", reviewerEmail); - return -1; + throw new IllegalAccessException("User not allowed to perform action"); } jitApproval.setReviewer(userService.findUserByEmail(reviewerEmail)); @@ -157,14 +161,16 @@ public class JitServiceImpl implements JitService { jitRequest.getId(), JitRequestStatus.REJECTED); - return flowFunction.apply(reviewerEmail, jitApproval, jitRequest, pendingReviewers, + flowFunction.apply(reviewerEmail, jitApproval, jitRequest, pendingReviewers, approvedReviewers, rejectedReviewers); + + return; } log.error("Illegal request"); - return -1; + throw new IllegalArgumentException("Invalid request. Could not be processed"); } - private Integer jitApprovedFlow( + private void jitApprovedFlow( String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest, @@ -193,48 +199,47 @@ public class JitServiceImpl implements JitService { actionEnabled = false; } // inform reviewer on slack that request is approved and remove action buttons - updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false, + SlackColor.APPROVED); // send group message to common channel with details on pending and approved reviewers updateChannelOnSlack(jitRequest, pendingReviewers, approvedReviewers, - rejectedReviewers); + rejectedReviewers, SlackColor.APPROVED); updateRequestorDmOnSlack(jitRequest, pendingReviewers, - approvedReviewers, rejectedReviewers, actionEnabled); + approvedReviewers, rejectedReviewers, actionEnabled, SlackColor.APPROVED); jitRequestRepository.save(jitRequest); jitApprovalsRepository.save(jitApproval); - return 0; } catch (Exception e) { log.error(ExceptionAirflowOrDb, e.getCause()); - return -1; + throw new ConnectException(ExceptionAirflowOrDb); } } - private Integer jitRejectedFlow( + private void jitRejectedFlow( String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest, List pendingReviewers, List approvedReviewers, List rejectedReviewers - ) { + ) throws ConnectException { try { jitApproval.setAction(JitRequestStatus.REJECTED); jitRequest.setStatus(JitRequestStatus.REJECTED); - updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false); + updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false, + SlackColor.REJECTED); updateRequestorDmOnSlack(jitRequest, pendingReviewers, - approvedReviewers, rejectedReviewers, false); + approvedReviewers, rejectedReviewers, false, SlackColor.REJECTED); updateChannelOnSlack(jitRequest, pendingReviewers, approvedReviewers, - rejectedReviewers); + rejectedReviewers, SlackColor.REJECTED); jitApprovalsRepository.save(jitApproval); jitRequestRepository.save(jitRequest); - - return 0; } catch (Exception e) { log.error(ExceptionAirflowOrDb, e.getCause()); - return -1; + throw new ConnectException(ExceptionAirflowOrDb); } } @@ -248,12 +253,12 @@ public class JitServiceImpl implements JitService { jitApproval.setAction(JitRequestStatus.CANCELLED); jitApprovalsRepository.save(jitApproval); updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, - false); + false, SlackColor.REJECTED); } updateChannelOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), - new ArrayList<>()); + new ArrayList<>(), SlackColor.REJECTED); updateRequestorDmOnSlack(jitRequest, new ArrayList<>(), - new ArrayList<>(), new ArrayList<>(), false); + new ArrayList<>(), new ArrayList<>(), false, SlackColor.REJECTED); jitRequestRepository.save(jitRequest); return 0; } catch (Exception e) { @@ -275,7 +280,7 @@ public class JitServiceImpl implements JitService { } @Override - public Boolean createJitRequest(JitRequestDto jitRequestDto) throws IOException { + public void createJitRequest(JitRequestDto jitRequestDto) throws IOException { // Map request DTO to JitRequest Entity and save in DB JitRequest jitRequest = mapToJitRequest(jitRequestDto); @@ -290,7 +295,7 @@ public class JitServiceImpl implements JitService { if (reviewers.size() == 0) { // no reviewers found, inform user updateRequestorNoReviewersDmOnSlack(jitRequest); - return true; + throw new IllegalStateException("No reviewers found"); } List jitApprovals = new ArrayList<>(); List pendingReviewers = new ArrayList<>(); @@ -308,41 +313,42 @@ public class JitServiceImpl implements JitService { // send personal message to user with details on pending and approved reviewers JitRequest jitRequestWithId = jitRequestRepository.save(jitRequest); updateRequestorDmOnSlack(jitRequestWithId, pendingReviewers, - new ArrayList<>(), new ArrayList<>(), true); + new ArrayList<>(), new ArrayList<>(), true, SlackColor.INFO); // send group message to common channel with details on pending and approved reviewers updateChannelOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), - new ArrayList<>()); + new ArrayList<>(), SlackColor.INFO); List jitApprovalsWithId = jitApprovalsRepository.saveAll(jitApprovals); JitRequest finalJitRequest = jitRequest; jitApprovalsWithId.stream().forEach(jitApproval -> { try { updateReviewerDmOnSlack(jitApproval.getReviewer(), - finalJitRequest, jitApproval, true); + finalJitRequest, jitApproval, true, SlackColor.INFO); } catch (IOException e) { throw new RuntimeException(e); } }); jitRequestRepository.save(jitRequest); - return true; } @Override - public Integer approveJitRequest(String approver, Long requestId) throws IOException { - return processJitRequest(approver, requestId, JitRequestStatus.APPROVED, + public void approveJitRequest(String approver, Long requestId) + throws IOException, IllegalAccessException { + processJitRequest(approver, requestId, JitRequestStatus.APPROVED, this::jitApprovedFlow); } @Override - public Integer rejectJitRequest(String rejecter, Long requestId) throws IOException { - return processJitRequest(rejecter, requestId, JitRequestStatus.REJECTED, + public void rejectJitRequest(String rejecter, Long requestId) + throws IOException, IllegalAccessException { + processJitRequest(rejecter, requestId, JitRequestStatus.REJECTED, this::jitRejectedFlow); } @Override - public JitResponseDto closeRequest(String closer, Long requestId) { + public void closeRequest(String closer, Long requestId) throws IllegalAccessException { Optional jitRequests = jitRequestRepository.findById(requestId); if (jitRequests.isPresent()) { JitRequest jitRequest = jitRequests.get(); @@ -351,17 +357,15 @@ public class JitServiceImpl implements JitService { jitCancelledFlow(jitRequest); } else { log.error("User {} not allowed to close request", closer); - return new JitResponseDto(-1, null, null); + throw new IllegalAccessException("User not allowed to close the request"); } - return new JitResponseDto(requestId, jitRequests.get().getStatus(), null); } - return null; } @FunctionalInterface interface JitFlowFunction { - Integer apply( + void apply( String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest, diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index 7bfae1d5..eeddb6ae 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -17,11 +17,15 @@ import org.springframework.stereotype.Component; @Component public class SlackBotUtil { - - private static final String SlackYellow = "#f2c744"; +// +// private static final String SlackOpen = "#f2c744"; +// private static final String SlackApproved = "#3ce336"; +// private static final String SlackInfo = "#44c0db"; +// private static final String SlackRejected = "#e03a48"; public SlackBotAttachment getReviewerDm( - String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled + String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled, + SlackColor color ) { ArrayList blocks = new ArrayList<>(); @@ -62,7 +66,7 @@ public class SlackBotUtil { blocks.add(reviewRequestAction); } - return new SlackBotAttachment(SlackYellow, blocks); + return new SlackBotAttachment(color.color, blocks); } public SlackBotAttachment getRequestorDm( @@ -72,7 +76,8 @@ public class SlackBotUtil { List pendingReviewers, List approvedReviewers, List rejectedReviewers, - String requestStatus + String requestStatus, + SlackColor color ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format("Access request raised for user %s\n" + "\tPending Reviewers: %s\n" @@ -99,7 +104,7 @@ public class SlackBotUtil { blocks.add(reviewRequestAction); } - return new SlackBotAttachment(SlackYellow, blocks); + return new SlackBotAttachment(color.color, blocks); } public SlackBotAttachment getRequestorNoReviewerDm( @@ -117,7 +122,7 @@ public class SlackBotUtil { ArrayList blocks = new ArrayList<>(); blocks.add(reviewRequestSection); - return new SlackBotAttachment(SlackYellow, blocks); + return new SlackBotAttachment(SlackColor.REJECTED.color, blocks); } public SlackBotAttachment getChannelMessage( @@ -125,7 +130,8 @@ public class SlackBotUtil { String email, List pendingReviewers, List approvedReviewers, - List rejectedReviewers + List rejectedReviewers, + SlackColor color ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format("Access request raised for user %s\n" + "\tPending Reviewers: %s\n" @@ -139,6 +145,6 @@ public class SlackBotUtil { ArrayList blocks = new ArrayList<>(); blocks.add(reviewRequestSection); - return new SlackBotAttachment(SlackYellow, blocks); + return new SlackBotAttachment(color.color, blocks); } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackColor.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackColor.java new file mode 100644 index 00000000..fd8ac222 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackColor.java @@ -0,0 +1,14 @@ +package com.navi.infra.portal.v2.jit.utils; + +public enum SlackColor { + OPEN("#f2c744"), + APPROVED("#3ce336"), + REJECTED("#e03a48"), + INFO("#44c0db"); + + public final String color; + + SlackColor(String color) { + this.color = color; + } +} diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java index 9abc665e..14601716 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -96,7 +96,6 @@ public class JitServiceImplTest { when(jitApprovalsRepository.saveAll(jitApprovals)).thenReturn(jitApprovalsWithId); when(jitRequestRepository.save(jitRequest)).thenReturn(jitRequest); - Boolean result = jitServiceImpl.createJitRequest(jitRequestDto); - Assertions.assertTrue(result); + jitServiceImpl.createJitRequest(jitRequestDto); } } diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java index 4ff341c9..84fbcd04 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java @@ -29,7 +29,7 @@ public class SlackBotUtilTest { jitApproval.setId(1L); SlackBotAttachment result = - slackBotUtil.getReviewerDm(userEmail, jitRequest, jitApproval, true); + slackBotUtil.getReviewerDm(userEmail, jitRequest, jitApproval, true, SlackColor.INFO); Assertions.assertEquals(2, result.getBlocks().size()); // Section + action block } @@ -39,7 +39,7 @@ public class SlackBotUtilTest { jitRequest.setId(2L); SlackBotAttachment result = slackBotUtil.getRequestorDm(userEmail, jitRequest, true, - new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), "PENDING"); + new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), "PENDING", SlackColor.INFO); Assertions.assertEquals(2, result.getBlocks().size()); // Section + action block } @@ -48,7 +48,7 @@ public class SlackBotUtilTest { public void testGroupMessage() { SlackBotAttachment result = slackBotUtil.getChannelMessage(jitRequest, userEmail, new ArrayList<>(), - new ArrayList<>(), new ArrayList<>()); + new ArrayList<>(), new ArrayList<>(), SlackColor.INFO); Assertions.assertEquals(1, result.getBlocks().size()); // Section } From 47090e0f7c4c05c42b0d3f2ef9d559ad21621a9c Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 29 Mar 2024 19:07:00 +0530 Subject: [PATCH 022/108] INFRA-2219 | Harinder | Updating AuthUtilTest for changed isAuthorized function --- .../infra/portal/v2/jit/utils/AuthUtilTest.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java index 7273effd..b6281c46 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import com.navi.infra.portal.domain.user.Role; import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; @@ -44,16 +45,16 @@ public class AuthUtilTest { @DisplayName("Check if the user authorized and has specific role") public void testIsAuthorized() { JitRequest jitRequest = new JitRequest(); - jitRequest.setTeam(new Team("TEAM")); + jitRequest.setTeam(new Team("Infra")); jitRequest.setEnvironment(Environment.PROD); - String userEmail = "alpha@one.com"; - List mockRoleIds = Collections.singletonList(123L); - List mockRoles = Collections.singletonList("TEAM_PROD_JITREVIEWER"); + String testEmail = "alpha@one.com"; + User testUser = new User(); + testUser.setEmail("alpha@one.com"); + List mockRoles = Collections.singletonList(new Role("Infra_prod_JITREVIEWER")); + testUser.setRoles(mockRoles); + when(userService.findUserByEmail(testEmail)).thenReturn(testUser); - when(userService.listAllRolesOfUser(userEmail)).thenReturn(mockRoleIds); - when(roleService.listAllAuthorities(mockRoleIds)).thenReturn(mockRoles); - - assertTrue(authUtil.isAuthorized(userEmail, jitRequest)); + assertTrue(authUtil.isAuthorized(testEmail, jitRequest)); } @Test From d4a4b6bfae6e290325ca558a1f81a78bd6371b45 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Sat, 30 Mar 2024 16:47:52 +0530 Subject: [PATCH 023/108] INFRA-2219 | Harinder | Restructuring query to users, role, users_roles table to find corresponding users who have a particular role. Removing ununsed service and repository functions --- .../portal/repository/UserRepository.java | 8 ------ .../portal/service/user/UserService.java | 9 +------ .../infra/portal/v2/role/RoleRepository.java | 12 +++++---- .../infra/portal/v2/role/RoleService.java | 7 ++---- .../infra/portal/v2/role/RoleServiceImpl.java | 25 +++++++++++-------- 5 files changed, 25 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/repository/UserRepository.java b/src/main/java/com/navi/infra/portal/repository/UserRepository.java index 6e71894a..b2b1a7e1 100644 --- a/src/main/java/com/navi/infra/portal/repository/UserRepository.java +++ b/src/main/java/com/navi/infra/portal/repository/UserRepository.java @@ -18,12 +18,4 @@ public interface UserRepository extends JpaRepository { @Query("SELECT u FROM User u WHERE lower(u.email) in (:emailList)") List> findAllByEmail(List emailList); - - @Query(value = "SELECT ur.user_id FROM users_roles ur WHERE ur.role_id = :roleId", - nativeQuery = true) - List findUserIdsByRoleIds(Long roleId); - - @Query(value = "SELECT ur.role_id FROM users_roles ur WHERE ur.user_id = :userId)", - nativeQuery = true) - List findAllRolesOfUser(Long userId); } diff --git a/src/main/java/com/navi/infra/portal/service/user/UserService.java b/src/main/java/com/navi/infra/portal/service/user/UserService.java index 9e0e8e5b..88aa4961 100644 --- a/src/main/java/com/navi/infra/portal/service/user/UserService.java +++ b/src/main/java/com/navi/infra/portal/service/user/UserService.java @@ -319,14 +319,7 @@ public class UserService { } public List getUsersWithRole(String roleName) { - Long roleId = roleService.findIdByName(roleName); - List userIds = userRepository.findUserIdsByRoleIds(roleId); - return userRepository.findAllById(userIds); - } - - public List listAllRolesOfUser(String email) { - Long id = userRepository.findIdByEmail(email); - return userRepository.findAllRolesOfUser(id); + return roleService.findUsersByRoleName(roleName); } private void syncUserEmailAndSlackId() throws IOException { diff --git a/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java b/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java index 97e7780f..aa92dce3 100644 --- a/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/role/RoleRepository.java @@ -1,7 +1,9 @@ package com.navi.infra.portal.v2.role; import com.navi.infra.portal.domain.user.Role; +import com.navi.infra.portal.domain.user.User; import java.util.List; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @@ -11,12 +13,12 @@ interface RoleRepository extends JpaRepository { Role findByName(String name); - @Query(value = "SELECT r.id FROM role r WHERE r.name = :name", nativeQuery = true) - Long findIdByName(String name); - List findByNameIn(List name); - @Query(value = "SELECT rp.privilege_id FROM roles_privileges rp WHERE rp.role_id = :roleId)", + @Query(value = "SELECT u.id, u.email, u.name, u.slack_id FROM users u " + + "JOIN users_roles ur ON u.id = ur.user_id " + + "JOIN role r ON ur.role_id = r.id " + + "WHERE r.name = :roleName", nativeQuery = true) - List findAllPrivilegessOfRole(Long roleId); + List findUsersByRoleName(String roleName); } diff --git a/src/main/java/com/navi/infra/portal/v2/role/RoleService.java b/src/main/java/com/navi/infra/portal/v2/role/RoleService.java index d65ade06..6990cdf9 100644 --- a/src/main/java/com/navi/infra/portal/v2/role/RoleService.java +++ b/src/main/java/com/navi/infra/portal/v2/role/RoleService.java @@ -2,6 +2,7 @@ package com.navi.infra.portal.v2.role; import com.navi.infra.portal.domain.user.Privilege; import com.navi.infra.portal.domain.user.Role; +import com.navi.infra.portal.domain.user.User; import java.util.List; import java.util.stream.Stream; @@ -9,8 +10,6 @@ public interface RoleService { List findByNameIn(List roles); - Long findIdByName(String role); - List saveAll(List roles); Stream createTeamRoleNames(String teamName); @@ -20,7 +19,5 @@ public interface RoleService { Stream mapPrivilegesToRoles(String teamName, List roles, List privileges); - List listAllPrivilegesOfRole(Long roleId); - - List listAllAuthorities(List privilegeIds); + List findUsersByRoleName(String roleName); } diff --git a/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java index aaf9a02f..abe38a98 100644 --- a/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/role/RoleServiceImpl.java @@ -33,7 +33,9 @@ import static org.apache.logging.log4j.util.Strings.join; import com.navi.infra.portal.domain.user.Privilege; import com.navi.infra.portal.domain.user.Role; +import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.v2.privilege.PrivilegeService; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -41,6 +43,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Primary; @@ -77,16 +80,18 @@ class RoleServiceImpl implements RoleService { } @Override - public Long findIdByName(String role) { - return repository.findIdByName(role); - } - - public List listAllPrivilegesOfRole(Long roleId) { - return repository.findAllPrivilegessOfRole(roleId); - } - - public List listAllAuthorities(List privilegeIds) { - return null; + public List findUsersByRoleName(String roleName) { + var userObjectList = repository.findUsersByRoleName(roleName); + return userObjectList.stream() + .map(objects -> { + var user = new User(); + user.setId(((BigInteger) objects[0]).longValue()); + user.setEmail((String) objects[1]); + user.setName((String) objects[2]); + user.setSlackId((String) objects[3]); + return user; + }) + .collect(toList()); } @Override From 9d22b490c64a3638f39db59e6c07ad70c62daa69 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Sat, 30 Mar 2024 16:49:46 +0530 Subject: [PATCH 024/108] INFRA-2219 | Harinder | Removing unused return statement from jitCancelledFlow() --- .../com/navi/infra/portal/v2/jit/service/JitServiceImpl.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index eaeba849..c2971077 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -243,7 +243,7 @@ public class JitServiceImpl implements JitService { } } - private Integer jitCancelledFlow(JitRequest jitRequest) { + private void jitCancelledFlow(JitRequest jitRequest) { try { jitRequest.setStatus(JitRequestStatus.CANCELLED); List jitApprovals = jitApprovalsRepository.findAllReviewsByJitId( @@ -260,10 +260,8 @@ public class JitServiceImpl implements JitService { updateRequestorDmOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), false, SlackColor.REJECTED); jitRequestRepository.save(jitRequest); - return 0; } catch (Exception e) { log.error(ExceptionAirflowOrDb, e.getCause()); - return -1; } } From 92987eee646b1d7c4638a3fbc04cd88879fdb315 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Sat, 30 Mar 2024 16:55:32 +0530 Subject: [PATCH 025/108] INFRA-2219 | Harinder | Adding Transaction annotation in JitServiceImpl --- .../com/navi/infra/portal/v2/jit/service/JitServiceImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index c2971077..48f87523 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -30,6 +30,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -120,6 +121,7 @@ public class JitServiceImpl implements JitService { : jitRequest.getGrantAt()); } + @Transactional private void processJitRequest( String reviewerEmail, Long requestId, @@ -216,6 +218,7 @@ public class JitServiceImpl implements JitService { } } + private void jitRejectedFlow( String reviewerEmail, JitApproval jitApproval, @@ -243,6 +246,7 @@ public class JitServiceImpl implements JitService { } } + @Transactional private void jitCancelledFlow(JitRequest jitRequest) { try { jitRequest.setStatus(JitRequestStatus.CANCELLED); From df8706985653633d795dbcba1694a5fa2f0c14f0 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Mon, 1 Apr 2024 14:56:05 +0530 Subject: [PATCH 026/108] INFRA-2219 | Harinder | Linting SlackbotUtils post color enum changes. --- .../com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java | 5 ----- .../com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java | 3 ++- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index eeddb6ae..7bb14fff 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -17,11 +17,6 @@ import org.springframework.stereotype.Component; @Component public class SlackBotUtil { -// -// private static final String SlackOpen = "#f2c744"; -// private static final String SlackApproved = "#3ce336"; -// private static final String SlackInfo = "#44c0db"; -// private static final String SlackRejected = "#e03a48"; public SlackBotAttachment getReviewerDm( String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled, diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java index 84fbcd04..b7a2e875 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java @@ -39,7 +39,8 @@ public class SlackBotUtilTest { jitRequest.setId(2L); SlackBotAttachment result = slackBotUtil.getRequestorDm(userEmail, jitRequest, true, - new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), "PENDING", SlackColor.INFO); + new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), "PENDING", + SlackColor.INFO); Assertions.assertEquals(2, result.getBlocks().size()); // Section + action block } From 902f0d5a3097be67abe2fda44df96cec256b1fe8 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Mon, 1 Apr 2024 23:42:51 +0530 Subject: [PATCH 027/108] INFRA-2219 | Harinder | Updates to Environment and Vertical enums. Updated UserService's findUserByEmail() to be be more idiomatic. Updating JitController's function to include @Valid where necessary --- .../portal/service/user/UserService.java | 7 ++---- .../v2/jit/controller/JitController.java | 6 ++--- .../portal/v2/jit/dto/JitRequestDto.java | 1 - .../portal/v2/jit/entity/Environment.java | 22 ++++++++++--------- .../infra/portal/v2/jit/entity/Vertical.java | 4 ++-- .../portal/v2/jit/service/JitServiceImpl.java | 2 +- .../infra/portal/v2/jit/utils/AuthUtil.java | 20 +---------------- 7 files changed, 21 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/service/user/UserService.java b/src/main/java/com/navi/infra/portal/service/user/UserService.java index 88aa4961..f9e89fa9 100644 --- a/src/main/java/com/navi/infra/portal/service/user/UserService.java +++ b/src/main/java/com/navi/infra/portal/service/user/UserService.java @@ -311,11 +311,8 @@ public class UserService { } public User findUserByEmail(String email) { - Optional optionalUser = userRepository.findByEmail(email); - if (optionalUser.isPresent()) { - return optionalUser.get(); - } - throw new UsernameNotFoundException(email + " not found"); + return userRepository.findByEmail(email) + .orElseThrow(() -> new UsernameNotFoundException(email + " not found")); } public List getUsersWithRole(String roleName) { diff --git a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java index d972616d..7e4d6992 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java @@ -45,7 +45,7 @@ public class JitController { @PostMapping("/approve/{reviewId}") public ResponseEntity approveJitRequest( - @RequestBody JitUserDto approver, + @Valid @RequestBody JitUserDto approver, @PathVariable Long reviewId ) { try { @@ -62,7 +62,7 @@ public class JitController { @PostMapping("/reject/{reviewId}") public ResponseEntity rejectJitRequest( - @RequestBody JitUserDto rejecter, + @Valid @RequestBody JitUserDto rejecter, @PathVariable Long reviewId ) { try { @@ -79,7 +79,7 @@ public class JitController { @PostMapping("/close/{id}") public ResponseEntity closeJitRequest( - @RequestBody JitUserDto closer, + @Valid @RequestBody JitUserDto closer, @PathVariable Long id ) { try { diff --git a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java index ccdd7668..35bdb6c9 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java @@ -12,7 +12,6 @@ import lombok.Setter; @Getter @Setter -//@Builder @NoArgsConstructor @AllArgsConstructor public class JitRequestDto { diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java index 55bc9dc3..178d89b8 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java @@ -1,19 +1,21 @@ package com.navi.infra.portal.v2.jit.entity; public enum Environment { - DEV("dev"), - QA("qa"), - PROD("prod"), - NONPROD("nonprod"), - CMD("cmd"), - PERF("perf"), - UAT("uat"), - DATA_PLATFORM_NONPROD("data-platform-nonprod"), - DATA_PLATFORM_PROD("data-platform-prod"); + DEV("dev", 1), + QA("qa", 1), + PROD("prod", 2), + NONPROD("nonprod", 1), + CMD("cmd", 2), + PERF("perf", 1), + UAT("uat", 1), + DATA_PLATFORM_NONPROD("data-platform-nonprod", 1), + DATA_PLATFORM_PROD("data-platform-prod", 2); public final String type; + public final Long approvals; - Environment(String type) { + Environment(String type, int approvals) { this.type = type; + this.approvals = (long) approvals; } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java index b1f3a81f..54cc1c78 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/Vertical.java @@ -1,12 +1,12 @@ package com.navi.infra.portal.v2.jit.entity; public enum Vertical { - INSURANCE("Insurance"), + INSURANCE("insurance"), NAVIPAY("navi-pay"), SA("sa"), LENDING("lending"), NAVIPPL("navi-ppl"), - AMC("lenging"); // intentional mapping + AMC("lending"); // intentional mapping public final String type; diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 48f87523..1065d5a8 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -301,7 +301,7 @@ public class JitServiceImpl implements JitService { } List jitApprovals = new ArrayList<>(); List pendingReviewers = new ArrayList<>(); - String messageTimestamp = ""; + for (User reviewer : reviewers) { JitApproval jitApproval = new JitApproval(jitRequest, reviewer, JitRequestStatus.PENDING); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 724d7ce7..727af739 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -60,25 +60,7 @@ public class AuthUtil { Environment env = jitRequest.getEnvironment(); Long approvedRequests = jitApprovalsRepository.findApprovedRequestsCount( jitRequest.getId()); - boolean approved = false; - switch (env) { - case PROD: - case CMD: - case DATA_PLATFORM_PROD: - approved = approvedRequests >= prodJitApprovalsCount; - break; - case NONPROD: - case DEV: - case QA: - case DATA_PLATFORM_NONPROD: - case UAT: - case PERF: - approved = approvedRequests >= nonprodJitApprovalsCount; - break; - default: - log.error("Invalid environment: {}", env); - } - return approved; + return approvedRequests >= env.approvals; } public List getReviewers(JitRequestDto jitRequestDto) { From 70b3ee313ed4786004628a9b00707de4c596ab3c Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Tue, 2 Apr 2024 13:19:42 +0530 Subject: [PATCH 028/108] INFRA-2219 | Harinder | Marking JitServiceImpl as package private and using the idiomatic way accessing optional objects --- .../portal/v2/jit/service/JitServiceImpl.java | 96 +++++++++---------- 1 file changed, 46 insertions(+), 50 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 1065d5a8..1b133ac4 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -35,7 +35,7 @@ import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @Slf4j -public class JitServiceImpl implements JitService { +class JitServiceImpl implements JitService { private static final String ExceptionAirflowOrDb = "Failed to connect to airflow or failed to flush to DB"; @@ -130,46 +130,42 @@ public class JitServiceImpl implements JitService { ) throws IOException, IllegalAccessException { Optional optionalJitApproval = jitApprovalsRepository.findById(requestId); - if (optionalJitApproval.isPresent()) { - JitApproval jitApproval = optionalJitApproval.get(); - JitRequest jitRequest = jitApproval.getJitRequest(); - if (jitApproval.getReviewedAt() != null - || !jitRequest.getStatus().equals(JitRequestStatus.PENDING)) { - log.error("Request already reviewed"); - throw new IllegalStateException("Request already reviewed"); - } - jitApproval.setReviewedAt(LocalDateTime.now()); - - if (!reviewerEmail.equals(jitApproval.getReviewer().getEmail()) - && !authUtil.isAuthorized(reviewerEmail, jitRequest) - && reviewerEmail.equals(jitRequest.getRequestedFor().getEmail())) { - log.error("User {} not allowed to perform action", reviewerEmail); - throw new IllegalAccessException("User not allowed to perform action"); - } - - jitApproval.setReviewer(userService.findUserByEmail(reviewerEmail)); - jitApproval.setAction(jitRequestStatus); - - jitApprovalsRepository.save(jitApproval); - // reviewer lists(pending, approved, rejected) and count of approvals depends on above - - List pendingReviewers = authUtil.getReviewersByAction(userService, - jitRequest.getId(), - JitRequestStatus.PENDING); - List approvedReviewers = authUtil.getReviewersByAction(userService, - jitRequest.getId(), - JitRequestStatus.APPROVED); - List rejectedReviewers = authUtil.getReviewersByAction(userService, - jitRequest.getId(), - JitRequestStatus.REJECTED); - - flowFunction.apply(reviewerEmail, jitApproval, jitRequest, pendingReviewers, - approvedReviewers, rejectedReviewers); - - return; + final JitApproval jitApproval = optionalJitApproval.orElseThrow( + () -> new IllegalArgumentException( + "Invalid request. Could not be processed. Reviewer is invalid")); + JitRequest jitRequest = jitApproval.getJitRequest(); + if (jitApproval.getReviewedAt() != null + || !jitRequest.getStatus().equals(JitRequestStatus.PENDING)) { + log.error("Request already reviewed"); + throw new IllegalStateException("Request already reviewed"); } - log.error("Illegal request"); - throw new IllegalArgumentException("Invalid request. Could not be processed"); + jitApproval.setReviewedAt(LocalDateTime.now()); + + if (!reviewerEmail.equals(jitApproval.getReviewer().getEmail()) + && !authUtil.isAuthorized(reviewerEmail, jitRequest) + && reviewerEmail.equals(jitRequest.getRequestedFor().getEmail())) { + log.error("User {} not allowed to perform action", reviewerEmail); + throw new IllegalAccessException("User not allowed to perform action"); + } + + jitApproval.setReviewer(userService.findUserByEmail(reviewerEmail)); + jitApproval.setAction(jitRequestStatus); + + jitApprovalsRepository.save(jitApproval); + // reviewer lists(pending, approved, rejected) and count of approvals depends on above + + List pendingReviewers = authUtil.getReviewersByAction(userService, + jitRequest.getId(), + JitRequestStatus.PENDING); + List approvedReviewers = authUtil.getReviewersByAction(userService, + jitRequest.getId(), + JitRequestStatus.APPROVED); + List rejectedReviewers = authUtil.getReviewersByAction(userService, + jitRequest.getId(), + JitRequestStatus.REJECTED); + + flowFunction.apply(reviewerEmail, jitApproval, jitRequest, pendingReviewers, + approvedReviewers, rejectedReviewers); } private void jitApprovedFlow( @@ -351,16 +347,16 @@ public class JitServiceImpl implements JitService { @Override public void closeRequest(String closer, Long requestId) throws IllegalAccessException { - Optional jitRequests = jitRequestRepository.findById(requestId); - if (jitRequests.isPresent()) { - JitRequest jitRequest = jitRequests.get(); - if (jitRequest.getRequestedFor().getEmail().equals(closer) && jitRequest.getStatus() - .equals(JitRequestStatus.PENDING)) { - jitCancelledFlow(jitRequest); - } else { - log.error("User {} not allowed to close request", closer); - throw new IllegalAccessException("User not allowed to close the request"); - } + Optional optionalJitRequest = jitRequestRepository.findById(requestId); + + JitRequest jitRequest = optionalJitRequest.orElseThrow( + () -> new IllegalArgumentException("JIT request not found")); + if (jitRequest.getRequestedFor().getEmail().equals(closer) && jitRequest.getStatus() + .equals(JitRequestStatus.PENDING)) { + jitCancelledFlow(jitRequest); + } else { + log.error("User {} not allowed to close request", closer); + throw new IllegalAccessException("User not allowed to close the request"); } } From 935d9d1012d39a42d9d17f3ed3f5230b1b11b6d7 Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Fri, 5 Apr 2024 12:28:32 +0530 Subject: [PATCH 029/108] INFRA-809 | Ashvin | Move jsonnet to kutegen (#864) * INFRA-809 | Ashvin | Replace jsonnet with kutegen * INFRA-809 | Ashvin | Install kutegen on build and test * INFRA-809 | Ashvin | Fix 'static' modifier out of order with the JLS suggestions in KutegenClient.java * INFRA-809 | Ashvin | Remove all templates files * INFRA-809 | Ashvin | Add kutegen submodule * INFRA-809 | Ashvin | Use go run kutegen instead of build This will save dev an extra step of building kutegen each time they make a change in the templates files and thus save time and effort. go.work file lets us run go build and run in the parent directory. * INFRA-809 | Ashvin | Remove redundant dirs from Dockerfile * INFRA-809 | Ashvin | Remove go build in maven file. This was causing various dependency issue in the build process. I will add a Makefile if there is a need in the future for now. For now all local development will be done using go run command so this will not be necessary. * INFRA-809 | Ashvin | Update kutegen version * INFRA-809 | Ashvin | Revert YAML support from kutegen * INFRA-809 | Ashvin | Rebase the commit to kutegen * INFRA-809 | Ashvin | Fix test Using changes in the kutegen * INFRA-809 | Ashvin | Remove the templates dir * INFRA-809 | Ashvin | Clean generated dirs with mvn clean --- .gitignore | 1 + .gitmodules | 3 + Dockerfile | 15 +- README.md | 1 + go.work | 3 + go.work.sum | 19 + gocd-templates/main.jsonnet | 5 - gocd-templates/material.jsonnet | 156 -- gocd-templates/pipeline_helper.jsonnet | 70 - gocd-templates/pipelines.jsonnet | 92 - .../sample-manifest/pipeline_manifest.json | 66 - gocd-templates/stages.jsonnet | 243 --- kutegen | 1 + pom.xml | 19 + .../service/gocd/PipelineManifestService.java | 15 +- .../kubernetes/KubernetesManifestService.java | 29 +- .../navi/infra/portal/util/JsonnetUtil.java | 19 - .../infra/portal/util/JsonnetUtilImpl.java | 68 - .../util/KubernetesManifestGenerator.java | 8 + .../navi/infra/portal/util/KutegenClient.java | 52 + .../v2/ingress/IngressGroupApplierImpl.java | 29 +- .../KubernetesManifestServiceTest.java | 10 +- .../gocd/PipelineManifestServiceTest.java | 6 + .../ingress/IngressGroupApplierImplTest.java | 8 +- .../kube_objects/kube_object_alb.json | 2 +- .../kube_object_alb_redirect.json | 2 +- .../kube_objects/kube_object_efs_pvc.json | 2 +- .../kube_objects/kube_object_fsx.json | 2 +- .../kube_objects/kube_object_prod_tsc.json | 2 +- .../kube_object_prod_with_maxsurge.json | 2 +- templates/README.md | 14 - templates/chaos_engine.jsonnet | 94 -- templates/chaos_experiment.jsonnet | 87 - templates/chaos_main.jsonnet | 118 -- templates/chaos_util.jsonnet | 6 - templates/chart.jsonnet | 29 - templates/cluster_values.jsonnet | 1487 ----------------- templates/common.jsonnet | 67 - templates/common_api_gateway.jsonnet | 213 --- templates/configmap.jsonnet | 20 - templates/cron_hpa_autoscaler.jsonnet | 34 - templates/default_alerts.jsonnet | 407 ----- templates/deployment.jsonnet | 29 - templates/deployment_manifest.jsonnet | 209 --- templates/deployment_util.jsonnet | 108 -- templates/dynamic_configuration.jsonnet | 22 - templates/efs_persistent_volume_claim.jsonnet | 34 - templates/elastic_search.jsonnet | 90 - .../elasticsearch_alerts_default.jsonnet | 186 --- templates/elasticsearch_secrets.jsonnet | 18 - .../elasticsearch_servicemonitor.jsonnet | 75 - templates/elasticsearch_sm_secrets.jsonnet | 18 - templates/elasticsearch_snapshots.jsonnet | 122 -- templates/flink_default_alerts.jsonnet | 238 --- templates/flink_deployment.jsonnet | 172 -- templates/flink_role_binding.jsonnet | 27 - templates/flink_service_account.jsonnet | 27 - templates/flink_session_job.jsonnet | 24 - templates/health_check_values.jsonnet | 65 - templates/hpa.jsonnet | 70 - templates/ingress.jsonnet | 189 --- templates/kibana.jsonnet | 60 - templates/kibana_ingress_endpoint.jsonnet | 83 - templates/load_balancer_util.jsonnet | 142 -- templates/main.jsonnet | 97 -- templates/manifest_util.jsonnet | 17 - templates/namespace_values.jsonnet | 19 - templates/pdb.jsonnet | 20 - templates/perf_utility.jsonnet | 289 ---- templates/pod_template.jsonnet | 363 ---- templates/port_map.jsonnet | 50 - templates/rollout.jsonnet | 31 - templates/rollout_analysis_template.jsonnet | 33 - templates/sandbox/access_role.jsonnet | 80 - templates/sandbox/access_role_binding.jsonnet | 26 - templates/sandbox/aws_iam_role.jsonnet | 36 - templates/sandbox/main.jsonnet | 53 - templates/sandbox/namespace.jsonnet | 17 - templates/sandbox/role_binding.jsonnet | 25 - templates/secret.jsonnet | 18 - templates/security_group.jsonnet | 32 - templates/service.jsonnet | 119 -- templates/service_monitor.jsonnet | 37 - templates/shared_ingress_config/main.jsonnet | 5 - .../shared_ingress.libsonnet | 75 - ...in:dev-internal:custom-group-name:dev.json | 34 - .../tests/jsonnetfile.json | 15 - .../tests/jsonnetfile.lock.json | 16 - .../tests/shared_ingress.jsonnet | 49 - templates/sidecar.jsonnet | 87 - templates/util.jsonnet | 96 -- templates/vars.jsonnet | 44 - templates/vpa.jsonnet | 60 - 93 files changed, 168 insertions(+), 7209 deletions(-) create mode 100644 .gitmodules create mode 100644 go.work create mode 100644 go.work.sum delete mode 100644 gocd-templates/main.jsonnet delete mode 100644 gocd-templates/material.jsonnet delete mode 100644 gocd-templates/pipeline_helper.jsonnet delete mode 100644 gocd-templates/pipelines.jsonnet delete mode 100644 gocd-templates/sample-manifest/pipeline_manifest.json delete mode 100644 gocd-templates/stages.jsonnet create mode 160000 kutegen delete mode 100644 src/main/java/com/navi/infra/portal/util/JsonnetUtil.java delete mode 100644 src/main/java/com/navi/infra/portal/util/JsonnetUtilImpl.java create mode 100644 src/main/java/com/navi/infra/portal/util/KubernetesManifestGenerator.java create mode 100644 src/main/java/com/navi/infra/portal/util/KutegenClient.java delete mode 100644 templates/README.md delete mode 100644 templates/chaos_engine.jsonnet delete mode 100644 templates/chaos_experiment.jsonnet delete mode 100644 templates/chaos_main.jsonnet delete mode 100644 templates/chaos_util.jsonnet delete mode 100644 templates/chart.jsonnet delete mode 100644 templates/cluster_values.jsonnet delete mode 100644 templates/common.jsonnet delete mode 100644 templates/common_api_gateway.jsonnet delete mode 100644 templates/configmap.jsonnet delete mode 100644 templates/cron_hpa_autoscaler.jsonnet delete mode 100644 templates/default_alerts.jsonnet delete mode 100644 templates/deployment.jsonnet delete mode 100644 templates/deployment_manifest.jsonnet delete mode 100644 templates/deployment_util.jsonnet delete mode 100644 templates/dynamic_configuration.jsonnet delete mode 100644 templates/efs_persistent_volume_claim.jsonnet delete mode 100644 templates/elastic_search.jsonnet delete mode 100644 templates/elasticsearch_alerts_default.jsonnet delete mode 100644 templates/elasticsearch_secrets.jsonnet delete mode 100644 templates/elasticsearch_servicemonitor.jsonnet delete mode 100644 templates/elasticsearch_sm_secrets.jsonnet delete mode 100644 templates/elasticsearch_snapshots.jsonnet delete mode 100644 templates/flink_default_alerts.jsonnet delete mode 100644 templates/flink_deployment.jsonnet delete mode 100644 templates/flink_role_binding.jsonnet delete mode 100644 templates/flink_service_account.jsonnet delete mode 100644 templates/flink_session_job.jsonnet delete mode 100644 templates/health_check_values.jsonnet delete mode 100644 templates/hpa.jsonnet delete mode 100644 templates/ingress.jsonnet delete mode 100644 templates/kibana.jsonnet delete mode 100644 templates/kibana_ingress_endpoint.jsonnet delete mode 100644 templates/load_balancer_util.jsonnet delete mode 100644 templates/main.jsonnet delete mode 100644 templates/manifest_util.jsonnet delete mode 100644 templates/namespace_values.jsonnet delete mode 100644 templates/pdb.jsonnet delete mode 100644 templates/perf_utility.jsonnet delete mode 100644 templates/pod_template.jsonnet delete mode 100644 templates/port_map.jsonnet delete mode 100644 templates/rollout.jsonnet delete mode 100644 templates/rollout_analysis_template.jsonnet delete mode 100644 templates/sandbox/access_role.jsonnet delete mode 100644 templates/sandbox/access_role_binding.jsonnet delete mode 100644 templates/sandbox/aws_iam_role.jsonnet delete mode 100644 templates/sandbox/main.jsonnet delete mode 100644 templates/sandbox/namespace.jsonnet delete mode 100644 templates/sandbox/role_binding.jsonnet delete mode 100644 templates/secret.jsonnet delete mode 100644 templates/security_group.jsonnet delete mode 100644 templates/service.jsonnet delete mode 100644 templates/service_monitor.jsonnet delete mode 100644 templates/shared_ingress_config/main.jsonnet delete mode 100644 templates/shared_ingress_config/shared_ingress.libsonnet delete mode 100644 templates/shared_ingress_config/tests/expected/ingress/nonprod.np.navi-tech.in:dev-internal:custom-group-name:dev.json delete mode 100644 templates/shared_ingress_config/tests/jsonnetfile.json delete mode 100644 templates/shared_ingress_config/tests/jsonnetfile.lock.json delete mode 100644 templates/shared_ingress_config/tests/shared_ingress.jsonnet delete mode 100644 templates/sidecar.jsonnet delete mode 100644 templates/util.jsonnet delete mode 100644 templates/vars.jsonnet delete mode 100644 templates/vpa.jsonnet diff --git a/.gitignore b/.gitignore index 400c3cbb..2c58a867 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ pipelines pipeline_manifests user-mapping.yaml **/vendor/ +bin/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..51c3de6f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "kutegen"] + path = kutegen + url = ../kutegen diff --git a/Dockerfile b/Dockerfile index 85152941..1602be51 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,18 @@ ARG BUILDER_CACHE_TARGET=193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/spring-boot-maven:1.0 + +FROM 193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/golang:1.21.1 as golang_builder +WORKDIR /app +COPY ./kutegen/go.mod ./kutegen/go.sum ./ +RUN go mod download +COPY ./kutegen ./ +RUN go build -o kutegen cmd/main.go + FROM ${BUILDER_CACHE_TARGET} as builder ARG ARTIFACT_VERSION=0.0.1-SNAPSHOT RUN rm -rf /build && mkdir -p /build WORKDIR /build COPY src /build/src COPY pom.xml /build -COPY templates /build/src/templates -COPY gocd-templates /build/src/gocd-templates -COPY scripts /build/src/scripts COPY entrypoint.sh /build/entrypoint.sh RUN wget -O elastic-apm.jar https://repo1.maven.org/maven2/co/elastic/apm/elastic-apm-agent/1.42.0/elastic-apm-agent-1.42.0.jar RUN mvn -Dhttps.protocols=TLSv1.2 -B dependency:resolve dependency:resolve-plugins @@ -20,10 +25,8 @@ WORKDIR /usr/local/ COPY --from=builder /build/elastic-apm.jar /usr/local/elastic-apm.jar COPY --from=builder /build/src/main/resources/elasticapm.properties /usr/local/elasticapm.properties COPY --from=builder /build/target/deployment-portal-backend-${ARTIFACT_VERSION}.jar /usr/local/deployment-portal-backend.jar -COPY --from=builder /build/src/templates /usr/local/templates -COPY --from=builder /build/src/gocd-templates /usr/local/gocd-templates -COPY --from=builder /build/src/scripts /usr/local/scripts COPY --from=builder /build/entrypoint.sh /usr/local/entrypoint.sh +COPY --from=golang_builder /app/kutegen /usr/local/bin/kutegen RUN apt-get update && \ apt-get install telnet curl dnsutils kafkacat -y && \ adduser --system --uid 4000 --disabled-password non-root-user && \ diff --git a/README.md b/README.md index b0cefc3f..135eee5f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Deployment Portal Backend +- Run `git submodule update --init --recursive` to pull the kutegen submodule. - Use `export ENVIRONMENT=test` to avoid applying changes to the cluster. - Docker Setup - To run the application just do `docker-compose up` diff --git a/go.work b/go.work new file mode 100644 index 00000000..40b57856 --- /dev/null +++ b/go.work @@ -0,0 +1,3 @@ +go 1.21.0 + +use ./kutegen diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 00000000..6c2412aa --- /dev/null +++ b/go.work.sum @@ -0,0 +1,19 @@ +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= +github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= +github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/gocd-templates/main.jsonnet b/gocd-templates/main.jsonnet deleted file mode 100644 index f68ad27a..00000000 --- a/gocd-templates/main.jsonnet +++ /dev/null @@ -1,5 +0,0 @@ -local pipelines = import 'pipelines.jsonnet'; - -{ - 'pipelines.json': pipelines, -} diff --git a/gocd-templates/material.jsonnet b/gocd-templates/material.jsonnet deleted file mode 100644 index 8b04f5fc..00000000 --- a/gocd-templates/material.jsonnet +++ /dev/null @@ -1,156 +0,0 @@ -local pipeline_helper = import 'pipeline_helper.jsonnet'; -local pipeline_manifest = import 'pipeline_manifest.json'; -local pipelines = pipeline_manifest.pipelines; -local name = pipeline_manifest.name; -local infraVertical = pipeline_manifest.infraVertical; - -local githubOrgMap = { - lending:: { - default:: 'git@github.com:navi-medici/', - prod:: self.default, - qa:: self.default, - dev:: self.default, - uat:: self.default, - perf:: self.default, - test:: self.default, - build:: self.default, - 'data-platform-prod':: 'git@github.com:navi-data/', - 'data-platform-nonprod':: 'git@github.com:navi-data/', - }, - insurance:: { - default:: 'git@github.com:navi-gi/', - prod:: self.default, - qa:: self.default, - dev:: self.default, - uat:: self.default, - perf:: self.default, - test:: self.default, - build:: self.default, - }, - infra:: { - default: 'git@github.com:navi-infra/', - prod:: self.default, - qa:: self.default, - dev:: self.default, - uat:: self.default, - perf:: self.default, - test:: self.default, - build:: self.default, - }, - amc:: { - default: 'git@github.com:navi-amc/', - prod:: self.default, - qa:: self.default, - dev:: self.default, - uat:: self.default, - perf:: self.default, - test:: self.default, - build:: self.default, - }, - sa:: { - default: 'git@github.com:navi-sa/', - prod:: self.default, - qa:: self.default, - dev:: self.default, - uat:: self.default, - perf:: self.default, - test:: self.default, - build:: self.default, - }, - colending:: { - default: 'git@github.com:navi-co-lending/', - prod:: self.default, - qa:: self.default, - dev:: self.default, - uat:: self.default, - perf:: self.default, - test:: self.default, - build:: self.default, - }, - 'navi-pay':: { - default: 'git@github.com:navi-pay/', - prod:: self.default, - qa:: self.default, - dev:: self.default, - uat:: self.default, - perf:: self.default, - test:: self.default, - build:: self.default, - }, - 'navi-saas':: { - default: 'git@github.com:navi-saas/', - prod:: self.default, - qa:: self.default, - dev:: self.default, - uat:: self.default, - perf:: self.default, - test:: self.default, - build:: self.default, - }, - 'navi-ppl':: { - default: 'git@github.com:navi-ppl/', - prod:: self.default, - qa:: self.default, - dev:: self.default, - uat:: self.default, - perf:: self.default, - test:: self.default, - build:: self.default, - }, -}; - -{ - getMaterial(name, env):: { - test:: { - plugin_configuration: { - id: 'github.pr', - version: '1.4.0-RC2', - }, - options: { - url: githubOrgMap[infraVertical][env] + name + '.git', - branch: 'master', - }, - destination: 'test', - }, - build:: { - git: { - git: githubOrgMap[infraVertical][env] + name + '.git', - shallow_clone: true, - branch: 'master', - }, - }, - 'rds-deploy':: { - mygit: { - git: githubOrgMap[infraVertical][env] + name + '.git', - shallow_clone: true, - branch: 'master', - }, - }, - 's3-deploy':: self['rds-deploy'], - 'iam-deploy':: self['rds-deploy'], - 'redis-deploy':: self['rds-deploy'], - 'docdb-deploy':: self['rds-deploy'], - 'migrate-deploy':: { - git: { - git: githubOrgMap[infraVertical][env] + name + '.git', - shallow_clone: true, - branch: 'master', - }, - }, - }, - getUpstreamMaterial(name, pipeline):: - (if pipeline.type == 'migrate-deploy' then { - code: { - pipeline: pipeline_helper.getUpstreamPipelineName(pipeline), - stage: pipeline_helper.getUpstreamPipelineStage(pipeline), - }, - } else {}), - material(name, pipeline):: $.getMaterial(name, pipeline.env)[pipeline.type] + $.getUpstreamMaterial(name, pipeline), - pipelineName(name, pipeline):: $.getPipelineName(name, pipeline.type, pipeline.env), - getPipelineName(name, type, env):: - if type == 'test' || type == 'build' then - (name + '-' + type) - else if type == 'rds-deploy' || type == 's3-deploy' || type == 'redis-deploy' || type == 'docdb-deploy' || type == 'iam-deploy' then - (name + '-' + env + '-all-resource-deploy') - else (name + '-' + env + '-' + type), -} diff --git a/gocd-templates/pipeline_helper.jsonnet b/gocd-templates/pipeline_helper.jsonnet deleted file mode 100644 index b40e0ca0..00000000 --- a/gocd-templates/pipeline_helper.jsonnet +++ /dev/null @@ -1,70 +0,0 @@ -local pipeline_manifest = import 'pipeline_manifest.json'; -local pipelines = pipeline_manifest.pipelines; -local name = pipeline_manifest.name; -local buildPipelineName = name + '-build'; -local devPipelineName = name + '-dev-migrate-deploy'; -local qaPipelineName = name + '-qa-migrate-deploy'; -local uatPipelineName = name + '-uat-migrate-deploy'; -local prodPipelineName = name + '-prod-migrate-deploy'; -local pipelineMap = { - [pipeline.env]: true - for pipeline in pipelines -}; -local approvalTypeMap(stages) = { -[stage.type]: stage.approvalType -for stage in stages -}; -local hasDevPipeline = std.objectHas(pipelineMap, 'dev'); -local hasQaPipeline = std.objectHas(pipelineMap, 'qa'); -local hasUatPipeline = std.objectHas(pipelineMap, 'uat'); -local hasProdPipeline = std.objectHas(pipelineMap, 'prod'); - -{ - getUpstreamPipelineName(pipeline):: ( - if pipeline.env == 'dev' then buildPipelineName - else if pipeline.env == 'qa' then ( - if hasDevPipeline then devPipelineName - else buildPipelineName - ) - else if pipeline.env == 'uat' then ( - if hasQaPipeline then qaPipelineName - else if hasDevPipeline then devPipelineName - else buildPipelineName - ) - else if pipeline.env == 'prod' then ( - if hasUatPipeline then uatPipelineName - else if hasQaPipeline then qaPipelineName - else if hasDevPipeline then devPipelineName - else buildPipelineName - ) - ), - getUpstreamPipelineStage(pipeline):: ( - if pipeline.env == 'dev' then 'build' - else if pipeline.env == 'qa' then (if hasDevPipeline then 'deploy' else 'build') - else if pipeline.env == 'uat' then (if (hasQaPipeline || hasDevPipeline) then 'deploy' else 'build') - else if pipeline.env == 'prod' then (if (hasQaPipeline || hasDevPipeline || hasUatPipeline) then 'deploy' else 'build') - ), - getUpstreamPipelineJob(pipeline):: $.getUpstreamPipelineStage(pipeline), - stageMap(pipeline):: { - [stage.type]: true - for stage in pipeline.stages - }, - artifactPipeline(pipeline):: - if pipeline.env == 'dev' then buildPipelineName - else if pipeline.env == 'qa' then ( - if hasDevPipeline then (buildPipelineName + '/' + devPipelineName) - else buildPipelineName - ) - else if pipeline.env == 'uat' then ( - buildPipelineName + - (if hasDevPipeline then ('/' + devPipelineName) else '') + - (if hasQaPipeline then ('/' + qaPipelineName) else '') - ) - else if pipeline.env == 'prod' then ( - buildPipelineName + - (if hasDevPipeline then ('/' + devPipelineName) else '') + - (if hasQaPipeline then ('/' + qaPipelineName) else '') + - (if hasUatPipeline then ('/' + uatPipelineName) else '') - ), - getApprovalType(allStages,stageType):: approvalTypeMap(allStages)[stageType] -} diff --git a/gocd-templates/pipelines.jsonnet b/gocd-templates/pipelines.jsonnet deleted file mode 100644 index 832b0a4a..00000000 --- a/gocd-templates/pipelines.jsonnet +++ /dev/null @@ -1,92 +0,0 @@ -local pipeline_manifest = import 'pipeline_manifest.json'; -local pipelines = pipeline_manifest.pipelines; -local name = pipeline_manifest.name; -local util = import 'material.jsonnet'; -local stage_util = import 'stages.jsonnet'; -local infraVertical = pipeline_manifest.infraVertical; - -local groupMap = { - lending: { - test: 'Medici-test', - build: 'Medici', - dev: 'Medici-deploy-dev', - qa: 'Medici-deploy-qa', - uat: 'Medici-deploy-uat', - prod: 'Medici-deploy-prod', - cmd: 'Infrastructure', - 'data-platform-prod': 'Data', - 'data-platform-nonprod': 'Data', - }, - insurance:: { - test:: 'GI-test', - build: 'GI', - dev: 'GI-deploy-dev', - qa: 'GI-deploy-qa', - uat: 'GI-deploy-uat', - prod: 'GI-deploy-prod', - }, - amc:: { - test:: 'amc-test', - build: 'amc', - dev: 'amc-deploy-dev', - qa: 'amc-deploy-qa', - prod: 'amc-deploy-prod', - }, - sa:: { - test:: 'SA-test', - build: 'SA', - dev: 'SA-deploy-dev', - qa: 'SA-deploy-qa', - uat: 'SA-deploy-uat', - prod: 'SA-deploy-prod', - }, - infra:: {}, - colending::{ - test:: 'Co-Lending-test', - build: 'Co-Lending', - dev: 'Co-Lending-deploy-dev', - qa: 'Co-Lending-deploy-qa', - prod: 'Co-Lending-deploy-prod', - }, - 'navi-pay'::{ - test:: 'Navi-Pay-deploy-dev', - build: 'Navi-Pay', - dev: 'Navi-Pay-deploy-dev', - qa: 'Navi-Pay-deploy-qa', - uat: 'Navi-Pay-deploy-uat', - prod: 'Navi-Pay-deploy-prod', - }, - 'navi-saas'::{ - test:: 'Navi-Saas-deploy-dev', - build: 'Navi-Saas', - dev: 'Navi-Saas-deploy-dev', - qa: 'Navi-Saas-deploy-qa', - prod: 'Navi-Saas-deploy-prod', - }, - 'navi-ppl'::{ - test:: 'Navi-PPL-deploy-dev', - build: 'Navi-PPL', - dev: 'Navi-PPL-deploy-dev', - qa: 'Navi-PPL-deploy-qa', - prod: 'Navi-PPL-deploy-prod', - }, -}; - - -{ - format_version: 3, - pipelines: { - [util.pipelineName(name, pipeline)]: { - group: groupMap[infraVertical][pipeline.env], - materials: (if pipeline.type == 'test' then { - [util.pipelineName(name, pipeline)]: util.material(name, pipeline), - } else util.material(name, pipeline)), - environment_variables: { - ENVIRONMENT: pipeline.env, - APP_NAME: name, - }, - stages: stage_util.getStages(pipeline), - }, - for pipeline in pipelines - }, -} diff --git a/gocd-templates/sample-manifest/pipeline_manifest.json b/gocd-templates/sample-manifest/pipeline_manifest.json deleted file mode 100644 index 325d21c5..00000000 --- a/gocd-templates/sample-manifest/pipeline_manifest.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "spring-boot-demo", - "pipelines": [ - { - "type": "test", - "env": "test", - "stages": [ - { - "type": "test" - } - ] - }, - { - "type": "build", - "env": "build", - "stages": [ - { - "type": "build" - } - ] - }, - { - "type": "migrate-deploy", - "env": "dev", - "stages": [ - { - "type": "migrate", - "approvalType":"auto" - }, - { - "type": "deploy", - "approvalType":"auto" - } - ] - }, - { - "type": "migrate-deploy", - "env": "qa", - "stages": [ - { - "type": "migrate", - "approvalType":"auto" - }, - { - "type": "deploy", - "approvalType":"auto" - } - ] - }, - { - "type": "migrate-deploy", - "env": "prod", - "stages": [ - { - "type": "migrate", - "approvalType":"manual" - }, - { - "type": "deploy", - "approvalType":"manual" - } - ] - } - ], - "infraVertical": "medici" -} \ No newline at end of file diff --git a/gocd-templates/stages.jsonnet b/gocd-templates/stages.jsonnet deleted file mode 100644 index 960231cd..00000000 --- a/gocd-templates/stages.jsonnet +++ /dev/null @@ -1,243 +0,0 @@ -local materialUtil = import 'material.jsonnet'; -local helpers = import 'pipeline_helper.jsonnet'; -local pipeline_manifest = import 'pipeline_manifest.json'; -local name = pipeline_manifest.name; -local pipelines = pipeline_manifest.pipelines; - -local elastic_profile_map = { - build: { - build: 'prod-default', - }, - test: { - test: 'prod-default', - }, - dev: { - migrate: 'prod-default', - deploy: 'nonprod-infra', - }, - qa: { - migrate: 'prod-default', - deploy: 'nonprod-infra', - }, - uat: { - migrate: 'prod-default', - deploy: 'nonprod-infra', - }, - prod: { - migrate: 'prod-default', - deploy: 'prod-infra', - }, -}; - -local infra_provisioner_arg = { - 'rds-deploy': 'database', - 's3-deploy': 's3-buckets', - 'iam-deploy': 'iam-roles', - 'redis-deploy': 'redis', - 'docdb-deploy': 'docdb', -}; - -{ - test(pipeline):: [ - { - test:{ - fetch_materials: true, - approval: { - type: 'success', - allow_only_on_success: false, - }, - jobs: { - test: { - timeout: 0, - elastic_profile_id: elastic_profile_map[pipeline.env].test, - tasks: [ - { - exec: { - command: 'bash', - arguments: [ - '-c', - 'git submodule update --remote --init', - ], - working_directory: 'test', - run_if: 'passed', - }, - }, - { - exec: { - arguments: [ - '-c', - 'eval $(aws ecr get-login --no-include-email --region ap-south-1 --registry-id 193044292705) && docker-compose up --abort-on-container-exit', - ], - command: 'bash', - run_if: 'passed', - working_directory: 'test', - }, - }, - ], - }, - }, - } - }, - ], - build(pipeline):: [ - { - build: { - fetch_materials: true, - jobs: { - build: { - timeout: 0, - elastic_profile_id: elastic_profile_map[pipeline.env].build, - tasks: [ - { - exec: { - arguments: [ - '-c', - 'docker-build' + ' ' + pipeline_manifest.name, - ], - command: 'bash', - run_if: 'passed', - }, - }, - ], - artifacts: [ - { - build: { - source: 'image_version', - destination: '', - }, - }, - ], - }, - }, - }, - }, - ], - migrate(pipeline):: [ - { - migration: { - fetch_materials: true, - approval: { - type: helpers.getApprovalType(pipeline.stages,'migrate'), - allow_only_on_success: false, - }, - jobs: { - migration: { - elastic_profile_id: elastic_profile_map[pipeline.env].migrate, - tasks: [ - { - fetch: { - is_file: true, - source: 'image_version', - destination: 'deployment', - pipeline: helpers.artifactPipeline(pipeline), - stage: 'build', - job: 'build', - run_if: 'passed', - }, - }, - { - script: ' cd deployment \n . fetch_config_portal \n eval $(aws ecr get-login --no-include-email --region ap-south-1 --registry-id 193044292705)\n docker run -w /usr/local \\ \n -e DATASOURCE_URL=${DATASOURCE_URL} -e DATASOURCE_USERNAME=${DATASOURCE_USERNAME} \\ \n -e DATASOURCE_PASSWORD=${DATASOURCE_PASSWORD} `cat image_version` java -jar database.jar', - }, - ], - }, - }, - }, - }, - ], - deploy(pipeline):: [ - { - deploy: { - fetch_materials: true, - approval: { - type: helpers.getApprovalType(pipeline.stages,'deploy'), - allow_only_on_success: false, - }, - jobs: { - deploy: { - timeout: 0, - elastic_profile_id: elastic_profile_map[pipeline.env].deploy, - tasks: [ - { - fetch: { - is_file: true, - source: 'image_version', - destination: 'deployment', - pipeline: helpers.artifactPipeline(pipeline), - stage: 'build', - job: 'build', - run_if: 'passed', - }, - }, - { - exec: { - arguments: [ - '-c', - 'portal_deploy ${ENVIRONMENT} `cat image_version`', - ], - command: 'bash', - run_if: 'passed', - working_directory: 'deployment', - }, - }, - ], - }, - }, - }, - }, - ], - deployAwsResourcesWithPlan(pipeline, type):: [ - { - plan: { - approval: { - type: "manual", - allow_only_on_success: false - }, - environment_variables: { - "ADDITIONAL_OPTIONS": "--plan" - }, - jobs: { - "deploy": { - elastic_profile_id: 'prod-infra', - tasks: [ - { - script: '. fetch_manifest\n infra-provisioner-v2 -m $MANIFEST ${ADDITIONAL_OPTIONS} all\n' - } - ] - } - } - } - }, - { - deploy: { - approval: { - type: "manual", - allow_only_on_success: false - }, - environment_variables: { - "ADDITIONAL_OPTIONS": "" - }, - jobs: { - "deploy": { - elastic_profile_id: 'prod-infra', - tasks: [ - { - script: ". fetch_manifest\n infra-provisioner-v2 -m $MANIFEST ${ADDITIONAL_OPTIONS} all\n" - } - ] - } - } - } - }, - ], - getStages(pipeline):: - if pipeline.type == 'test' then $.test(pipeline) - else if pipeline.type == 'build' then $.build(pipeline) - else if pipeline.type == 'migrate-deploy' then ( - (if std.objectHas(helpers.stageMap(pipeline), 'migrate') then $.migrate(pipeline) else []) + - (if std.objectHas(helpers.stageMap(pipeline), 'deploy') then $.deploy(pipeline) else []) - ) else if pipeline.type == 'rds-deploy' || - pipeline.type == 's3-deploy' || - pipeline.type == 'redis-deploy' || - pipeline.type == 'docdb-deploy' || - pipeline.type == 'iam-deploy' then $.deployAwsResourcesWithPlan(pipeline, infra_provisioner_arg[pipeline.type]) -} diff --git a/kutegen b/kutegen new file mode 160000 index 00000000..b23e2ded --- /dev/null +++ b/kutegen @@ -0,0 +1 @@ +Subproject commit b23e2dedf69914135c95dd8bab5537518aa3aba8 diff --git a/pom.xml b/pom.xml index d75b99ab..23f0140d 100644 --- a/pom.xml +++ b/pom.xml @@ -325,6 +325,25 @@ + + maven-clean-plugin + + + + ${project.basedir}/kubernetes_manifests + + + ${project.basedir}/manifests + + + ${project.basedir}/pipeline_manifests + + + ${project.basedir}/pipelines + + + + diff --git a/src/main/java/com/navi/infra/portal/service/gocd/PipelineManifestService.java b/src/main/java/com/navi/infra/portal/service/gocd/PipelineManifestService.java index 159e3bde..ab8034e8 100644 --- a/src/main/java/com/navi/infra/portal/service/gocd/PipelineManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/gocd/PipelineManifestService.java @@ -3,7 +3,7 @@ package com.navi.infra.portal.service.gocd; import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.domain.gocd.PipelineManifest; import com.navi.infra.portal.repository.PipelineManifestRepository; -import com.navi.infra.portal.util.JsonnetUtil; +import com.navi.infra.portal.util.KubernetesManifestGenerator; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; @@ -30,8 +30,6 @@ import org.springframework.web.server.ResponseStatusException; public class PipelineManifestService { private final String PIPELINE_MANIFEST_PATH = "pipeline_manifests"; - private final String PIPELINE_TEMPLATES_FOLDER = "gocd-templates"; - private final String mainJsonnet = "main.jsonnet"; private final String PIPELINE_YAML_PATH = "pipelines"; private final String PIPELINE_MANIFEST_FILE_NAME = "pipeline_manifest.json"; private final String PIPELINE_YAML_FILE_NAME = "pipelines.json"; @@ -40,7 +38,7 @@ public class PipelineManifestService { private final PipelineManifestRepository pipelineManifestRepository; - private final JsonnetUtil jsonnetUtil; + private final KubernetesManifestGenerator kubernetesManifestGenerator; public List pipelineManifestList() { return pipelineManifestRepository @@ -88,9 +86,12 @@ public class PipelineManifestService { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); PrintStream printStream = new PrintStream(byteArrayOutputStream, false, StandardCharsets.UTF_8); - var exitCode = jsonnetUtil.generateKManifests(getPipelinesManifestPath(pipelineManifest), - getPipelinesPath(pipelineManifest), printStream, new String[]{}, mainJsonnet, - PIPELINE_TEMPLATES_FOLDER); + var exitCode = kubernetesManifestGenerator.generate( + printStream, new String[]{"gocd-pipeline", + "-f", getPipelinesManifestPath(pipelineManifest) + PIPELINE_MANIFEST_FILE_NAME, + "-o", getPipelinesPath(pipelineManifest) + } + ); if (exitCode != 0) { throw new RuntimeException(String.format("Could not generate manifests %s", diff --git a/src/main/java/com/navi/infra/portal/service/kubernetes/KubernetesManifestService.java b/src/main/java/com/navi/infra/portal/service/kubernetes/KubernetesManifestService.java index 41e55c73..d7ed6fcf 100644 --- a/src/main/java/com/navi/infra/portal/service/kubernetes/KubernetesManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/kubernetes/KubernetesManifestService.java @@ -31,7 +31,7 @@ import com.navi.infra.portal.domain.manifest.StatusMarker; import com.navi.infra.portal.dto.manifest.SecurityGroup; import com.navi.infra.portal.exceptions.KubernetesManifestException; import com.navi.infra.portal.service.manifest.DeploymentService; -import com.navi.infra.portal.util.JsonnetUtil; +import com.navi.infra.portal.util.KubernetesManifestGenerator; import com.navi.infra.portal.util.MapDiffUtil; import com.navi.infra.portal.util.kubernetes.KubernetesManifestUtils; import io.kubernetes.client.openapi.ApiException; @@ -71,8 +71,6 @@ import org.springframework.stereotype.Service; @Slf4j public class KubernetesManifestService { - private static final String JSONNET_TEMPLATES_FOLDER = "templates"; - private static final String GENERATED_KUBERNETES_MANIFEST_FOLDER = "kubernetes_manifests"; private static final String MANIFEST_INPUT_FILE_PATH = "manifests"; @@ -93,7 +91,7 @@ public class KubernetesManifestService { private final String environment; - private final JsonnetUtil jsonnetUtil; + private final KubernetesManifestGenerator kubernetesManifestGenerator; private final KubeClient kubeClient; private final long securityGroupIdFetchRetryFixedBackoff; @@ -104,7 +102,7 @@ public class KubernetesManifestService { ObjectMapper objectMapper, Executor executor, @Value("${ENVIRONMENT:test}") String environment, - JsonnetUtil jsonnetUtil, + KubernetesManifestGenerator kubernetesManifestGenerator, KubeClient kubeClient, @Value("${kubernetes.security-group.id.fetch.fixed-backoff.interval}") long securityGroupIdFetchRetryFixedBackoff, @Value("${kubernetes.security-group.id.fetch.fixed-backoff.max-attempts}") int securityGroupIdFetchRetryMaxAttempts @@ -113,7 +111,7 @@ public class KubernetesManifestService { this.objectMapper = objectMapper; this.executor = executor; this.environment = environment; - this.jsonnetUtil = jsonnetUtil; + this.kubernetesManifestGenerator = kubernetesManifestGenerator; this.kubeClient = kubeClient; this.securityGroupIdFetchRetryFixedBackoff = securityGroupIdFetchRetryFixedBackoff; this.securityGroupIdFetchRetryMaxAttempts = securityGroupIdFetchRetryMaxAttempts; @@ -132,7 +130,7 @@ public class KubernetesManifestService { public void generateManifestsAndApply(Manifest manifest) { if (manifest.getDeployment() != null) { - final String kManifestPath = generateManifests(manifest, null); + final String kManifestPath = generateManifests(manifest, "null"); log.info("Generated kubernetes manifests at {}", kManifestPath); if (environment.equals("test")) { log.info( @@ -340,8 +338,10 @@ public class KubernetesManifestService { PrintStream printStream = new PrintStream(byteArrayOutputStream, false, StandardCharsets.UTF_8); String writePath = getKubernetesManifestPath(manifest); - int exitCode = generateKManifests(getManifestPath(manifest), writePath, printStream, - new String[]{"--ext-str", "IMAGE=" + image }, mainJsonnet); + int exitCode = generateKManifests(printStream, + new String[]{"generate", "--image", image, + "--file", getManifestPath(manifest) + MANIFEST_INPUT_FILE_NAME, + "--output", writePath}); if (exitCode > 0) { throw new KubernetesManifestException( format("Not able to generate kubernetes manifests: %s", @@ -501,15 +501,8 @@ public class KubernetesManifestService { return jsonObject; } - private int generateKManifests( - String readPath, - String writePath, - PrintStream ps, - String[] jsonnetAdditionalOptions, - String mainJsonnet - ) { - return jsonnetUtil.generateKManifests(readPath, writePath, ps, jsonnetAdditionalOptions, - mainJsonnet, JSONNET_TEMPLATES_FOLDER); + private int generateKManifests(PrintStream ps, String[] jsonnetAdditionalOptions) { + return kubernetesManifestGenerator.generate(ps, jsonnetAdditionalOptions); } /** diff --git a/src/main/java/com/navi/infra/portal/util/JsonnetUtil.java b/src/main/java/com/navi/infra/portal/util/JsonnetUtil.java deleted file mode 100644 index ebc808b3..00000000 --- a/src/main/java/com/navi/infra/portal/util/JsonnetUtil.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.navi.infra.portal.util; - -import java.io.PrintStream; - -public interface JsonnetUtil { - - int generateKManifests( - String readPath, String writePath, PrintStream ps, - String[] jsonnetAdditionalOptions, String mainJsonnet, String jsonnetTemplatesFolder - ); - - int run( - String writePath, - PrintStream ps, - String[] jsonnetAdditionalOptions, - String mainJsonnet, - String jsonnetTemplatesFolder - ); -} diff --git a/src/main/java/com/navi/infra/portal/util/JsonnetUtilImpl.java b/src/main/java/com/navi/infra/portal/util/JsonnetUtilImpl.java deleted file mode 100644 index 89010fea..00000000 --- a/src/main/java/com/navi/infra/portal/util/JsonnetUtilImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.navi.infra.portal.util; - -import static java.lang.System.arraycopy; -import static scala.None$.empty; - -import java.io.PrintStream; -import org.springframework.stereotype.Component; -import os.package$; -import sjsonnet.DefaultParseCache; -import sjsonnet.SjsonnetMain; - -@Component -public class JsonnetUtilImpl implements JsonnetUtil { - - @Override - public int generateKManifests( - String readPath, String writePath, PrintStream ps, - String[] jsonnetAdditionalOptions, String mainJsonnet, String jsonnetTemplatesFolder - ) { - - String[] jsonnetOptions = new String[]{jsonnetTemplatesFolder + "/" + mainJsonnet, "-J", - readPath, "-c", "-m", writePath}; - - return run(jsonnetOptions, jsonnetAdditionalOptions, ps); - } - - @Override - public int run( - String writePath, - PrintStream ps, - String[] jsonnetAdditionalOptions, - String mainJsonnet, - String jsonnetTemplatesFolder - ) { - String[] jsonnetOptions = new String[]{jsonnetTemplatesFolder + "/" + mainJsonnet, - "-c", "-m", writePath}; - - return run(jsonnetOptions, jsonnetAdditionalOptions, ps); - } - - private static int run( - String[] options, - String[] additionalOptions, - PrintStream ps - ) { - PrintStream stdErr = System.err; - System.setErr(ps); - - try { - var jsonnetCommand = new String[additionalOptions.length + options.length]; - arraycopy(options, 0, jsonnetCommand, 0, options.length); - arraycopy(additionalOptions, 0, jsonnetCommand, options.length, - additionalOptions.length); - - return SjsonnetMain.main0(jsonnetCommand, - new DefaultParseCache(), - System.in, - System.out, - System.err, - package$.MODULE$.pwd(), - empty(), - empty() - ); - } finally { - System.setErr(stdErr); - } - } -} diff --git a/src/main/java/com/navi/infra/portal/util/KubernetesManifestGenerator.java b/src/main/java/com/navi/infra/portal/util/KubernetesManifestGenerator.java new file mode 100644 index 00000000..2492fb87 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/util/KubernetesManifestGenerator.java @@ -0,0 +1,8 @@ +package com.navi.infra.portal.util; + +import java.io.PrintStream; + +public interface KubernetesManifestGenerator { + + int generate(PrintStream ps, String[] args); +} diff --git a/src/main/java/com/navi/infra/portal/util/KutegenClient.java b/src/main/java/com/navi/infra/portal/util/KutegenClient.java new file mode 100644 index 00000000..9bd73d9e --- /dev/null +++ b/src/main/java/com/navi/infra/portal/util/KutegenClient.java @@ -0,0 +1,52 @@ +package com.navi.infra.portal.util; + +import static java.lang.System.arraycopy; + +import java.io.PrintStream; +import java.util.Arrays; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class KutegenClient implements KubernetesManifestGenerator { + + private final String[] kutegenPath; + + public KutegenClient(@Value("${ENVIRONMENT:test}") String environment) { + if (environment.equals("test")) { + kutegenPath = new String[]{"go", "run", "kutegen/cmd/main.go"}; + } else { + kutegenPath = new String[]{"bin/kutegen"}; + } + } + + @Override + public int generate(PrintStream ps, String[] args) { + final var exitCode = run(args, ps); + log.info("Kutegen exit code: {}", exitCode); + return exitCode; + } + + private int run(String[] args, PrintStream errorStream) { + final var stdErr = System.err; + System.setErr(errorStream); + + try { + final var command = new String[kutegenPath.length + args.length]; + + arraycopy(kutegenPath, 0, command, 0, kutegenPath.length); + arraycopy(args, 0, command, kutegenPath.length, args.length); + + log.info("Running kutegen with options: {}", Arrays.toString(command)); + final var processBuilder = new ProcessBuilder(command); + final var process = processBuilder.inheritIO().start(); + return process.waitFor(); + } catch (Exception e) { + throw new RuntimeException("Error running kutegen", e); + } finally { + System.setErr(stdErr); + } + } +} diff --git a/src/main/java/com/navi/infra/portal/v2/ingress/IngressGroupApplierImpl.java b/src/main/java/com/navi/infra/portal/v2/ingress/IngressGroupApplierImpl.java index 88f92a04..c018b054 100644 --- a/src/main/java/com/navi/infra/portal/v2/ingress/IngressGroupApplierImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/ingress/IngressGroupApplierImpl.java @@ -9,7 +9,7 @@ import static java.util.Objects.requireNonNull; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.exceptions.KubernetesManifestException; -import com.navi.infra.portal.util.JsonnetUtil; +import com.navi.infra.portal.util.KubernetesManifestGenerator; import com.navi.infra.portal.util.kubernetes.KubernetesManifestUtils; import java.io.ByteArrayOutputStream; import java.io.File; @@ -33,7 +33,7 @@ public class IngressGroupApplierImpl implements IngressGroupApplier { private final String kubernetesManifestsPath; - private final JsonnetUtil jsonnetUtil; + private final KubernetesManifestGenerator kubernetesManifestGenerator; private final KubernetesManifestUtils kubernetesManifestUtils; private final ObjectMapper jsonMapper; @@ -41,13 +41,13 @@ public class IngressGroupApplierImpl implements IngressGroupApplier { public IngressGroupApplierImpl( @Value("templates/shared_ingress_config") String jsonnetTemplatesFolder, @Value("kubernetes_manifests") String kubernetesManifestsPath, - JsonnetUtil jsonnetUtil, + KubernetesManifestGenerator kubernetesManifestGenerator, KubernetesManifestUtils kubernetesManifestUtils, @Qualifier("jsonMapper") ObjectMapper jsonMapper ) { this.jsonnetTemplatesFolder = jsonnetTemplatesFolder; this.kubernetesManifestsPath = kubernetesManifestsPath; - this.jsonnetUtil = jsonnetUtil; + this.kubernetesManifestGenerator = kubernetesManifestGenerator; this.kubernetesManifestUtils = kubernetesManifestUtils; this.jsonMapper = jsonMapper; } @@ -72,23 +72,18 @@ public class IngressGroupApplierImpl implements IngressGroupApplier { } private String createK8sManifest(IngressGroupCreateRequest request, String writePath) { - final var jsonnetAdditionalOptions = new String[]{ - "--tla-str", "cluster=" + request.getCluster(), - "--tla-str", "namespace=" + request.getNamespace(), - "--tla-str", "group_name=" + request.getName(), - "--tla-str", "environment=" + request.getEnvironment(), - "--tla-str", "product=" + request.getProduct() + final var args = new String[]{"shared-alb-config", + "--output", writePath, + "--cluster", request.getCluster(), + "--namespace", request.getNamespace(), + "--group_name", request.getName(), + "--environment", request.getEnvironment(), + "--product", request.getProduct() }; var byteArrayOutputStream = new ByteArrayOutputStream(); var ps = new PrintStream(byteArrayOutputStream, false, UTF_8); - var exitCode = jsonnetUtil.run( - writePath, - ps, - jsonnetAdditionalOptions, - "main.jsonnet", - jsonnetTemplatesFolder - ); + var exitCode = kubernetesManifestGenerator.generate(ps, args); if (exitCode > 0) { throw new KubernetesManifestException( diff --git a/src/test/java/com/navi/infra/portal/service/KubernetesManifestServiceTest.java b/src/test/java/com/navi/infra/portal/service/KubernetesManifestServiceTest.java index ad77f435..d2faf96e 100644 --- a/src/test/java/com/navi/infra/portal/service/KubernetesManifestServiceTest.java +++ b/src/test/java/com/navi/infra/portal/service/KubernetesManifestServiceTest.java @@ -21,8 +21,8 @@ import com.navi.infra.portal.provider.Common; import com.navi.infra.portal.service.kubernetes.BashExecute; import com.navi.infra.portal.service.kubernetes.KubernetesManifestService; import com.navi.infra.portal.service.manifest.DeploymentService; -import com.navi.infra.portal.util.JsonnetUtil; -import com.navi.infra.portal.util.JsonnetUtilImpl; +import com.navi.infra.portal.util.KubernetesManifestGenerator; +import com.navi.infra.portal.util.KutegenClient; import com.navi.infra.portal.util.MapDiffUtil; import io.kubernetes.client.openapi.ApiException; import java.io.IOException; @@ -55,7 +55,7 @@ public class KubernetesManifestServiceTest { private final BashExecute bashExecute; - private final JsonnetUtil jsonnetUtil; + private final KubernetesManifestGenerator kubernetesManifestGenerator; private final KubeClient kubeClient; @@ -67,10 +67,10 @@ public class KubernetesManifestServiceTest { deploymentService = Mockito.mock(DeploymentService.class); bashExecute = Mockito.mock(BashExecute.class); kubeClient = Mockito.mock(KubeClient.class); - jsonnetUtil = new JsonnetUtilImpl(); + kubernetesManifestGenerator = new KutegenClient("test"); kubernetesManifestService = new KubernetesManifestService(deploymentService, objectMapper, - bashExecute, "dev", jsonnetUtil, kubeClient, 2000L, + bashExecute, "dev", kubernetesManifestGenerator, kubeClient, 2000L, 5); } diff --git a/src/test/java/com/navi/infra/portal/service/gocd/PipelineManifestServiceTest.java b/src/test/java/com/navi/infra/portal/service/gocd/PipelineManifestServiceTest.java index 65d998c9..e46f2774 100644 --- a/src/test/java/com/navi/infra/portal/service/gocd/PipelineManifestServiceTest.java +++ b/src/test/java/com/navi/infra/portal/service/gocd/PipelineManifestServiceTest.java @@ -4,6 +4,7 @@ import com.navi.infra.portal.domain.gocd.PipelineManifest; import com.navi.infra.portal.provider.ExternalIntegrationProvider; import java.io.IOException; import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; @@ -19,6 +20,11 @@ public class PipelineManifestServiceTest extends ExternalIntegrationProvider { @Autowired private PipelineManifestService pipelineManifestService; + @BeforeAll + static void setUp() { + System.setProperty("ENVIRONMENT", "test"); + } + private void assertJsonEqual(String inputFile, String expectedFile) throws IOException { String pipelineManifestJson = FileUtils .readFileToString(ResourceUtils.getFile(inputFile), "UTF-8"); diff --git a/src/test/java/com/navi/infra/portal/v2/ingress/IngressGroupApplierImplTest.java b/src/test/java/com/navi/infra/portal/v2/ingress/IngressGroupApplierImplTest.java index a2eddd6e..6fb84be5 100644 --- a/src/test/java/com/navi/infra/portal/v2/ingress/IngressGroupApplierImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/ingress/IngressGroupApplierImplTest.java @@ -7,7 +7,7 @@ import static org.mockito.Mockito.when; import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.exceptions.KubernetesManifestException; import com.navi.infra.portal.service.kubernetes.BashExecute; -import com.navi.infra.portal.util.JsonnetUtil; +import com.navi.infra.portal.util.KubernetesManifestGenerator; import com.navi.infra.portal.util.kubernetes.KubernetesManifestUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -20,7 +20,7 @@ import org.mockito.junit.jupiter.MockitoExtension; class IngressGroupApplierImplTest { @Mock - private JsonnetUtil jsonnetUtil; + private KubernetesManifestGenerator kubernetesManifestGenerator; private IngressGroupApplier ingressGroupApplier; @@ -28,7 +28,7 @@ class IngressGroupApplierImplTest { @BeforeEach void setup() { - ingressGroupApplier = new IngressGroupApplierImpl("", "", jsonnetUtil, + ingressGroupApplier = new IngressGroupApplierImpl("", "", kubernetesManifestGenerator, new KubernetesManifestUtils( new BashExecute(), "test"), jsonMapper); } @@ -39,7 +39,7 @@ class IngressGroupApplierImplTest { var createRequest = new IngressGroupCreateRequest("name", "namespace", "cluster", "environment", "product"); - when(jsonnetUtil.run(any(), any(), any(), any(), any())).thenReturn(1); + when(kubernetesManifestGenerator.generate(any(), any())).thenReturn(1); assertThrows(KubernetesManifestException.class, () -> ingressGroupApplier.createAndApply(createRequest)); diff --git a/src/test/resources/fixtures/kube_objects/kube_object_alb.json b/src/test/resources/fixtures/kube_objects/kube_object_alb.json index b6b6b502..2cd0f35c 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_alb.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_alb.json @@ -258,7 +258,7 @@ }, { "name": "secretMd5", - "value": "ca5855f61008767291e629652da57dc6" + "value": "d74618e323ae5b8a83fa496eb16ef003" } ], "ports": [ diff --git a/src/test/resources/fixtures/kube_objects/kube_object_alb_redirect.json b/src/test/resources/fixtures/kube_objects/kube_object_alb_redirect.json index 4d4736b9..fbabe090 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_alb_redirect.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_alb_redirect.json @@ -242,7 +242,7 @@ }, { "name": "secretMd5", - "value": "ca5855f61008767291e629652da57dc6" + "value": "d74618e323ae5b8a83fa496eb16ef003" } ], "ports": [ diff --git a/src/test/resources/fixtures/kube_objects/kube_object_efs_pvc.json b/src/test/resources/fixtures/kube_objects/kube_object_efs_pvc.json index cde24723..cdd6b1fb 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_efs_pvc.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_efs_pvc.json @@ -225,7 +225,7 @@ }, { "name": "secretMd5", - "value": "ca5855f61008767291e629652da57dc6" + "value": "d74618e323ae5b8a83fa496eb16ef003" } ], "image": "IMAGE", diff --git a/src/test/resources/fixtures/kube_objects/kube_object_fsx.json b/src/test/resources/fixtures/kube_objects/kube_object_fsx.json index e429bc32..2c690432 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_fsx.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_fsx.json @@ -225,7 +225,7 @@ }, { "name": "secretMd5", - "value": "ca5855f61008767291e629652da57dc6" + "value": "d74618e323ae5b8a83fa496eb16ef003" } ], "image": "IMAGE", diff --git a/src/test/resources/fixtures/kube_objects/kube_object_prod_tsc.json b/src/test/resources/fixtures/kube_objects/kube_object_prod_tsc.json index 6a9935b8..de774c99 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_prod_tsc.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_prod_tsc.json @@ -242,7 +242,7 @@ }, { "name": "secretMd5", - "value": "129cd9ea6fd37de0e07a8ff94467306f" + "value": "8a40bdadb732b9107fbf1eba768a302a" } ], "ports": [ diff --git a/src/test/resources/fixtures/kube_objects/kube_object_prod_with_maxsurge.json b/src/test/resources/fixtures/kube_objects/kube_object_prod_with_maxsurge.json index 24259656..82e1055f 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_prod_with_maxsurge.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_prod_with_maxsurge.json @@ -242,7 +242,7 @@ }, { "name": "secretMd5", - "value": "129cd9ea6fd37de0e07a8ff94467306f" + "value": "8a40bdadb732b9107fbf1eba768a302a" } ], "ports": [ diff --git a/templates/README.md b/templates/README.md deleted file mode 100644 index 72a54060..00000000 --- a/templates/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## Steps to test JSONNET changes - -1. Create a temporary directory in templates directory: - - ```mkdir /templates/temp``` - -2. Change directory to the same - - ```cd /templates/temp``` - -3. Run the following command to create json for testing purposes: - ```jsonnet main.jsonnet -J /manifests// --ext-str IMAGE='image' -m temp``` - -4. Inspect the jsonnets in temp folder. \ No newline at end of file diff --git a/templates/chaos_engine.jsonnet b/templates/chaos_engine.jsonnet deleted file mode 100644 index 3243431b..00000000 --- a/templates/chaos_engine.jsonnet +++ /dev/null @@ -1,94 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local chaos_util = import 'chaos_util.jsonnet'; - - -local env = function(experiment) { - latencyInjection: [ - { - name: 'NETWORK_LATENCY', - value: experiment.details.latency, - }, - ], - packetLoss: [ - { - name: 'NETWORK_PACKET_LOSS_PERCENTAGE', - value: experiment.details.packetLoss, - }, - ], -}[experiment.type]; - - -std.map(function(experiment) { - apiVersion: 'litmuschaos.io/v1alpha1', - kind: 'ChaosEngine', - metadata: { - name: '%s-chaos' % deployment.name, - namespace: deployment.namespace, - labels: { - resource_id: '%s-chaos' % deployment.name, - }, - }, - spec: { - jobCleanUpPolicy: 'delete', - annotationCheck: 'true', - engineState: 'active', - auxiliaryAppInfo: '', - monitoring: false, - appinfo: { - appns: deployment.namespace, - applabel: 'release=%s' % deployment.name, - appkind: 'deployment', - }, - chaosServiceAccount: '%s-sa' % chaos_util.experimentName(experiment), - components: { - runner: { - runnerannotation: { - 'sidecar.istio.io/inject': 'false', - }, - }, - }, - experiments: [{ - name: chaos_util.experimentName(experiment), - spec: { - components: { - experimentannotation: { - 'sidecar.istio.io/inject': 'false', - }, - env: [ - { - name: 'CHAOS_NAMESPACE', - value: deployment.namespace, - }, - { - name: 'APP_NAMESPACE', - value: deployment.namespace, - }, - { - name: 'NETWORK_INTERFACE', - value: 'eth0', - }, - { - name: 'TARGET_CONTAINER', - value: chart.full_service_name(deployment.name), - }, - { - name: 'TOTAL_CHAOS_DURATION', - value: experiment.duration, - }, - { - name: 'PODS_AFFECTED_PERC', - value: '100', - }, - { - name: 'TARGET_HOSTS', - value: std.join(',', experiment.details.targetHosts), - }, - ] + env(experiment), - }, - }, - }], - }, -}, deployment.faults) diff --git a/templates/chaos_experiment.jsonnet b/templates/chaos_experiment.jsonnet deleted file mode 100644 index 8de4fcf8..00000000 --- a/templates/chaos_experiment.jsonnet +++ /dev/null @@ -1,87 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local chaos_util = import 'chaos_util.jsonnet'; - -local descriptionMessage = function(experiment) { - latencyInjection: 'Injects network latency on pods belonging to an app deployment\n', - packetLoss: 'Injects network packet loss on pods belonging to an app deployment\n', -}[experiment.type]; - -local args = function(experiment) { - latencyInjection: './experiments/pod-network-latency', - packetLoss: './experiments/pod-network-loss', -}[experiment.type]; - -std.map( - function(experiment) - { - apiVersion: 'litmuschaos.io/v1alpha1', - description: { - message: descriptionMessage(experiment), - }, - kind: 'ChaosExperiment', - metadata: { - name: chaos_util.experimentName(experiment), - }, - spec: { - definition: { - scope: 'Namespaced', - permissions: [ - { - apiGroups: [ - '', - 'batch', - 'litmuschaos.io', - ], - resources: [ - 'jobs', - 'pods', - 'pods/log', - 'events', - 'chaosengines', - 'chaosexperiments', - 'chaosresults', - ], - verbs: [ - 'create', - 'list', - 'get', - 'patch', - 'update', - 'delete', - ], - }, - ], - image: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/litmus-go:1.8.1', - imagePullPolicy: 'Always', - args: [ - '-c', - args(experiment), - ], - command: [ - '/bin/bash', - ], - env: [ - { - name: 'NETWORK_INTERFACE', - value: 'eth0', - }, - { - name: 'LIB_IMAGE', - value: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/litmus-go:1.8.1', - }, - { - name: 'TC_IMAGE', - value: 'gaiadocker/iproute2', - }, - ], - labels: { - name: chaos_util.experimentName(experiment), - }, - }, - }, - }, - deployment.faults -) diff --git a/templates/chaos_main.jsonnet b/templates/chaos_main.jsonnet deleted file mode 100644 index 77234cf5..00000000 --- a/templates/chaos_main.jsonnet +++ /dev/null @@ -1,118 +0,0 @@ -local chaos_engines = import 'chaos_engine.jsonnet'; -local chaos_experiments = import 'chaos_experiment.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local chaos_util = import 'chaos_util.jsonnet'; - -local chaos_sa = function(experiment) { - apiVersion: 'v1', - kind: 'ServiceAccount', - metadata: { - labels: { - name: '%s-sa' % chaos_util.experimentName(experiment), - }, - name: '%s-sa' % chaos_util.experimentName(experiment), - namespace: deployment.namespace, - }, -}; - -local chaos_role = function(experiment) { - apiVersion: 'rbac.authorization.k8s.io/v1', - kind: 'Role', - metadata: { - labels: { - name: '%s-sa' % chaos_util.experimentName(experiment), - }, - name: '%s-sa' % chaos_util.experimentName(experiment), - namespace: deployment.namespace, - }, - rules: [ - { - apiGroups: [ - '', - 'litmuschaos.io', - 'batch', - ], - resources: [ - 'pods', - 'jobs', - 'pods/log', - 'events', - 'chaosengines', - 'chaosexperiments', - 'chaosresults', - ], - verbs: [ - 'create', - 'list', - 'get', - 'patch', - 'update', - 'delete', - ], - }, - ], -}; - -local chaos_rolebinding = function(experiment) { - apiVersion: 'rbac.authorization.k8s.io/v1', - kind: 'RoleBinding', - metadata: { - labels: { - name: '%s-sa' % chaos_util.experimentName(experiment), - }, - name: '%s-sa' % chaos_util.experimentName(experiment), - namespace: deployment.namespace, - }, - roleRef: { - apiGroup: 'rbac.authorization.k8s.io', - kind: 'Role', - name: '%s-sa' % chaos_util.experimentName(experiment), - }, - subjects: [ - { - kind: 'ServiceAccount', - name: '%s-sa' % chaos_util.experimentName(experiment), - }, - ], -}; - -local chaos_privileged_rolebinding = function(experiment) { - apiVersion: 'rbac.authorization.k8s.io/v1', - kind: 'RoleBinding', - metadata: { - name: 'psp:privileged:%s-sa' % chaos_util.experimentName(experiment), - namespace: deployment.namespace, - }, - roleRef: { - apiGroup: 'rbac.authorization.k8s.io', - kind: 'ClusterRole', - name: 'psp:privileged', - }, - subjects: [ - { - kind: 'ServiceAccount', - name: '%s-sa' % chaos_util.experimentName(experiment), - }, - ], -}; - -local getFiles = function(s, fn) { - [s % index]: fn(deployment.faults[index]) - for index in std.range(0, std.length(chaos_experiments) - 1) -}; - - -if 'faults' in deployment && std.length(deployment.faults) > 0 then - (if chaos_experiments != null then { - ['1_%s_chaos_experiment.json' % index]: chaos_experiments[index] - for index in std.range(0, std.length(chaos_experiments) - 1) - } else {}) + - getFiles('2_%s_chaos_sa.json', chaos_sa) + - getFiles('3_%s_chaos_role.json', chaos_role) + - getFiles('4_%s_chaos_rolebinding.json', chaos_rolebinding) + - getFiles('5_%s_chaos_privileged_rolebinding.json', chaos_privileged_rolebinding) + - (if chaos_engines != null then { - ['6_%s_chaos_engine.json' % index]: chaos_engines[index] - for index in std.range(0, std.length(chaos_engines) - 1) - } else {}) diff --git a/templates/chaos_util.jsonnet b/templates/chaos_util.jsonnet deleted file mode 100644 index 9e3b49dd..00000000 --- a/templates/chaos_util.jsonnet +++ /dev/null @@ -1,6 +0,0 @@ -{ - experimentName:: function(experiment) { - latencyInjection: 'pod-network-latency', - packetLoss: 'pod-network-loss', - }[experiment.type], -} diff --git a/templates/chart.jsonnet b/templates/chart.jsonnet deleted file mode 100644 index 4b4d9999..00000000 --- a/templates/chart.jsonnet +++ /dev/null @@ -1,29 +0,0 @@ -{ - //Private values - values:: { - apiVersion: 'v1', - name: 'navi-service', - description: 'Deploy navi services to kubernetes', - version: '0.0.1', - appVersion: '0.1', - home: 'https://github.cmd.navi-tech.in/navi-infra', - maintainers: [ - { - name: 'Infra', - email: 'infra-team@navi.com', - }, - ], - }, - - //Public functions - service_name: self.values.name, - - full_service_name(deployment_name): ( - assert std.length(deployment_name) <= 63 : 'Service name must be less than 63 characters. name: %s' % deployment_name; - local name = '%s-%s' % [deployment_name, self.service_name]; - assert std.length(name) <= 253 : 'Full Service name must be less than 253 characters. name: %s' % name; - name - ), - - service_chart: '%s-%s' % [self.values.name, self.values.version], -} diff --git a/templates/cluster_values.jsonnet b/templates/cluster_values.jsonnet deleted file mode 100644 index 05f2b073..00000000 --- a/templates/cluster_values.jsonnet +++ /dev/null @@ -1,1487 +0,0 @@ -{ - baseCluster+:: { - loadBalancer+:: { - sourceRanges:: ['1.1.1.1/32'], - annotations+:: { - webAcl:: 'dummy-webacl', - deletionProtection:: false, - accessLog:: true, - subnets+:: {}, - }, - }, - commonApiGateway+:: { - externalAuth:: { - config:: { - url:: 'dummyUrl', - }, - }, - }, - sidecarEnabled:: true, - zalandoEnabled:: true, - isEfsSupported: false, - isFsxSupported: false, - isVpaDeployed:: true, - isSwApmEnabled:: false - }, - - // Perf Endpoints - perfDomainEndpoint:: { - lending: '.np.navi-tech.in', - insurance: '.np.navi-gi.in', - sa: '.np.navi-sa.in', - amc: '.np.navi-amc.in', - }, - - //Non Prod cluster - 'nonprod.np.navi-tech.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'lending', - }, - flinkBucket: 'navi-flink-nonprod', - isEfsSupported: true, - isFsxSupported: true, - awsAccountId: 571315076762, - loadBalancer+:: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:571315076762:regional/webacl/AclNonProd/9ad3e612-4125-42ec-ab83-9e83ce95ac22', - securityGroups+:: { - //This security group allows packets from everywhere - internetFacing:: 'sg-01bbd376d7004403e', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-01a64c085bfdb2cbb', - - //This security group allows inter k8 cluster communication - internal:: 'sg-0bc07e856d000a5f4', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-022aa76e816973224', - - // Cloudflare ips - cdn:: 'sg-04abaea56b3db4697', - }, - sslCert:: { - 'np.navi-tech.in':: 'arn:aws:acm:ap-south-1:571315076762:certificate/a19c398a-639b-45ca-b885-4cf6002a16dc', - 'np.navi-ext.com':: 'arn:aws:acm:ap-south-1:571315076762:certificate/d9f5aac3-daee-401a-9035-b3f89a348d21', - 'navibank.ph':: 'arn:aws:acm:ap-south-1:571315076762:certificate/a19c398a-639b-45ca-b885-4cf6002a16dc', - 'navi.com':: 'arn:aws:acm:ap-south-1:571315076762:certificate/a19c398a-639b-45ca-b885-4cf6002a16dc', - }, - subnets:: { - internal:: 'internal-lb-ap-south-1a.nonprod.np.navi-tech.in,internal-lb-ap-south-1b.nonprod.np.navi-tech.in', - }, - accessLogBucket:: 'navi-nonprod-lb-access-logs', - accessLog: true, - }, - }, - }, - qa:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-services-alb', - }, - }, - }, - dev:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-services-alb', - }, - }, - }, - automation:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'automation-services-alb', - }, - fixedHostNames+:: { - 'mobile-application': 'automation-api.navi.com', - }, - }, - }, - 'qa-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-internal-services-alb', - }, - }, - }, - perf:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'perf-services-alb', - }, - }, - }, - 'dev-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-internal-services-alb', - }, - }, - }, - 'dev-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-critical-services-alb', - }, - }, - }, - 'qa-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-critical-services-alb', - }, - }, - }, - 'dev-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-3p-services-alb', - }, - fixedHostNames+:: { - 'mobile-application': 'dev-api.navi.com', - }, - }, - }, - 'qa-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-3p-services-alb', - }, - fixedHostNames+:: { - 'mobile-application': 'qa-api.navi.com', - }, - }, - }, - }, - - //CMD cluster - 'prod.cmd.navi-tech.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'shared', - }, - isVpaDeployed:: false, - awsAccountId: 193044292705, - loadBalancer+:: { - annotations+:: { - securityGroups+:: { - - //This security group allows inter k8 cluster communication - internal:: 'sg-05a07c526f95eeb77', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-07e815976f838974d', - - // Cloudflare IPs - cdn:: 'sg-030f711a697aefbcd', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-0c46b6742d741ef56', - }, - sslCert:: { - 'cmd.navi-tech.in':: 'arn:aws:acm:ap-south-1:193044292705:certificate/f5746e77-f3e0-467b-b09e-3f6f2bd33d5d', - }, - accessLog:: true, - accessLogBucket:: 'navi-cmd-lb-access-logs', - }, - }, - sidecarEnabled:: false, - }, - }, - - //GI nonprod cluster - 'aps1.np.navi-gi.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'gi', - }, - commonApiGateway+:: { - externalAuth:: { - config:: { - url:: 'https://test-ops-auth-service.np.navi-gi.in/auth', - }, - }, - }, - flinkBucket: 'navi-flink-gi-nonprod', - awsAccountId: 883430762451, - loadBalancer+:: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:883430762451:regional/webacl/AclNonProdGi/63c08952-a0ca-4f20-b237-ebebc3e6b45e', - securityGroups+:: { - - //This security group allows inter k8 cluster communication - internal:: 'sg-095f4e72442a3b1cb', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-092a892e2ed92f934', - - //This security group allows packets from everywhere - internetFacing:: 'sg-00f702563af978c17', - - natIp:: 'sg-0bbe47680861cb3af', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-05ed65ea26e845f6b', - - // CF ips - cdn:: 'sg-0101e7a8058f3ff90', - }, - sslCert:: { - 'np.navi-gi.in':: 'arn:aws:acm:ap-south-1:883430762451:certificate/fc0dbd8e-7754-48ac-b5f1-dc5614f918f1', - 'navi.com':: 'arn:aws:acm:ap-south-1:883430762451:certificate/cbd7d693-ef24-44c7-a26c-44cbe198cc89', - }, - accessLog:: true, - accessLogBucket:: 'aps1.np.navi-gi.in-alb-access-logs', - subnets:: { - internal: 'internal-lb-ap-south-1a.aps1.np.navi-gi.in,internal-lb-ap-south-1b.aps1.np.navi-gi.in', - }, - }, - }, - }, - qa:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-services-alb', - }, - }, - }, - dev:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-services-alb', - }, - }, - }, - 'qa-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-internal-services-alb', - }, - }, - }, - perf:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'perf-services-alb', - }, - }, - }, - 'dev-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-internal-services-alb', - }, - }, - }, - 'dev-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-critical-services-alb', - }, - }, - }, - 'qa-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-critical-services-alb', - }, - }, - }, - 'dev-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-3p-services-alb', - }, - }, - }, - 'qa-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-3p-services-alb', - }, - }, - }, - }, - - 'aps1.np.navi-amc.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'amc', - }, - loadBalancer+:: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:667580634104:regional/webacl/AclNonProdAmc/354559db-49fc-465c-9b30-fd84d4583c40', - securityGroups+:: { - - //This security group allows inter k8 cluster communication(nodes security group) - internal:: 'sg-02acb03253f80d846', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0655b24320f15a3c7', - - //This security group allows packets from everywhere - internetFacing:: 'sg-0064b8d763e4ee8a6', - - natIp:: 'sg-03986fe435275bce3', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-09c7dc317585f77fe', - }, - sslCert:: { - 'np.navi-amc.in':: 'arn:aws:acm:ap-south-1:667580634104:certificate/d6b73d36-d83b-4a75-aec3-bb05b8c995a4', - 'navi.com':: 'arn:aws:acm:ap-south-1:667580634104:certificate/d6b73d36-d83b-4a75-aec3-bb05b8c995a4', - }, - accessLog:: true, - accessLogBucket:: 'aps1.np.navi-amc.in-alb-access-logs', - subnets:: { - internal: 'ap-south-1a.aps1.np.navi-amc.in,ap-south-1b.aps1.np.navi-amc.in,ap-south-1c.aps1.np.navi-amc.in', - }, - }, - }, - }, - qa:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-services-alb', - }, - }, - }, - dev:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-services-alb', - }, - }, - }, - 'qa-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-internal-services-alb', - }, - }, - }, - perf:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'perf-services-alb', - }, - }, - }, - 'dev-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-internal-services-alb', - }, - }, - }, - 'dev-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-critical-services-alb', - }, - }, - }, - 'qa-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-critical-services-alb', - }, - }, - }, - 'dev-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-3p-services-alb', - }, - }, - }, - 'qa-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-3p-services-alb', - }, - }, - }, - }, - - 'aps1.np.navi-sa.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'sa', - }, - flinkBucket: 'navi-flink-sa-nonprod', - awsAccountId: 197185947855, - loadBalancer+:: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:197185947855:regional/webacl/AclNonProdSa/bbb07e35-7353-41d2-8603-fcbac4adf181', - securityGroups+:: { - - //This security group allows inter k8 cluster communication(nodes security group) - internal:: 'sg-0800f97f9c4cf731b', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0c954334a33a84784', - - //This security group allows packets from everywhere - internetFacing:: 'sg-00abfe4eb79cb607b', - - natIp:: 'sg-01d5ec5d474097cae', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-079bf73b2288f63ae', - - // Cloudflare ips - cdn:: 'sg-023c2b1a40cdae68d', - }, - sslCert:: { - 'np.navi-sa.in':: 'arn:aws:acm:ap-south-1:197185947855:certificate/a8025483-daf3-49f9-8528-4ffa4683ce88', - 'navi.com':: 'arn:aws:acm:ap-south-1:197185947855:certificate/a8025483-daf3-49f9-8528-4ffa4683ce88', - 'loangy.com':: 'arn:aws:acm:ap-south-1:197185947855:certificate/202f2edf-51ff-4b8d-97af-84750f8d15cf', - 'nuford.com':: 'arn:aws:acm:ap-south-1:197185947855:certificate/68208769-4040-4b29-842f-a1034c5f338a', - }, - accessLogBucket:: 'aps1.np.navi-sa.in-alb-access-logs', - accessLog:: true, - subnets:: { - internal: 'ap-south-1a.aps1.np.navi-sa.in,ap-south-1b.aps1.np.navi-sa.in,ap-south-1c.aps1.np.navi-sa.in', - }, - }, - }, - isSwApmEnabled:: false, - }, - qa:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-services-alb', - }, - }, - }, - 'navi-ops-tech-qa':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-services-alb', - }, - }, - }, - 'navi-ops-tech-dev':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-services-alb', - }, - }, - }, - dev:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-services-alb', - }, - }, - }, - 'qa-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-internal-services-alb', - }, - }, - }, - perf:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'perf-services-alb', - }, - }, - }, - 'dev-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-internal-services-alb', - }, - }, - }, - 'dev-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-critical-services-alb', - }, - }, - }, - 'qa-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-critical-services-alb', - }, - }, - }, - 'dev-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-3p-services-alb', - }, - }, - }, - 'qa-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-3p-services-alb', - }, - }, - }, - }, - - // sa-prod - 'aps1.prod.navi-sa.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'sa', - }, - flinkBucket: 'navi-flink-sa-prod', - awsAccountId: 120419666648, - isVpaDeployed:: true, - loadBalancer+: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:120419666648:regional/webacl/AclMASProdSa/3cd8ff0b-716b-4342-aa69-9592bc98055d', - securityGroups+:: { - //This security group allows packets from everywhere - internetFacing:: 'sg-0eefc892db09982c2', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0fe034c75aa465ef3', - - //This security group allows inter k8 cluster communication - internal:: 'sg-011f3fb53e6506486', - - //This security group allows communication from nat gateways of prod cluster - natIp:: 'sg-03b3400e9107cf8bc', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-0853dd98badfed3bd', - - // Cloudflare ips - cdn:: 'sg-01ee5bcb8640e2a1a', - }, - sslCert:: { - 'prod.navi-sa.in':: 'arn:aws:acm:ap-south-1:120419666648:certificate/196a820c-feec-4005-a7fd-a51ed72d4329', - 'navi.com':: 'arn:aws:acm:ap-south-1:120419666648:certificate/196a820c-feec-4005-a7fd-a51ed72d4329', - 'navi.net':: 'arn:aws:acm:ap-south-1:120419666648:certificate/fdfab80c-fc67-4005-938c-05b1188508ee', - 'loangy.com':: 'arn:aws:acm:ap-south-1:120419666648:certificate/a9494b99-c325-4058-bd51-807a3c8227a9', - 'nuford.com':: 'arn:aws:acm:ap-south-1:120419666648:certificate/d96e7a0d-8a14-46a0-92da-95a13faedf3f', - 'navifinserv.com':: 'arn:aws:acm:ap-south-1:120419666648:certificate/15f090d7-608c-4938-911c-6244a9922eb6', - }, - subnets:: { - internal: 'ap-south-1a.aps1.prod.navi-sa.in,ap-south-1b.aps1.prod.navi-sa.in,ap-south-1c.aps1.prod.navi-sa.in', - }, - accessLogBucket:: 'aps1.prod.navi-sa.in-alb-access-logs', - accessLog:: true, - deletionProtection:: false, - }, - }, - }, - 'prod-3p':: self.default { - loadBalancer+:: { - fixedHostNames+:: { - 'mobile-application': 'sa-api.navi.com', - }, - }, - }, - }, - - //PROD cluster - 'aps1.prod.navi-tech.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'lending', - }, - flinkBucket: 'navi-flink-prod', - isEfsSupported: true, - isFsxSupported: true, - awsAccountId: 492941056607, - isVpaDeployed:: true, - loadBalancer+: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:492941056607:regional/webacl/AclProd/fa85bcff-3c71-434c-be4f-dc4e0456c47d', - securityGroups+:: { - //This security group allows packets from everywhere - internetFacing:: 'sg-0a4e70d66a8a8bc34', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0df3121be8adc2fbc', - - //This security group allows inter k8 cluster communication - internal:: 'sg-064d258429b99b518', - - //This security group allows communication from nat gateways of prod cluster - natIp:: 'sg-0c7fb31b9b27e5e6f', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-032733713f4787bdc', - - cdn:: 'sg-09317e0e354c7f81f', - }, - sslCert:: { - 'prod.navi-tech.in':: 'arn:aws:acm:ap-south-1:492941056607:certificate/07a548dc-249d-4475-8783-58e3060b0c3f', - 'prod.navi-ext.com':: 'arn:aws:acm:ap-south-1:492941056607:certificate/0a3af671-4e93-415a-a05d-7f4d7dead5dc', - 'navi-ext.com':: 'arn:aws:acm:ap-south-1:492941056607:certificate/0a3af671-4e93-415a-a05d-7f4d7dead5dc', - 'navi.com':: 'arn:aws:acm:ap-south-1:492941056607:certificate/50681498-31f5-4117-8b42-8d0662ab5e93', - 'go-nlc.com':: 'arn:aws:acm:ap-south-1:492941056607:certificate/0ae1b16f-855c-48ca-bcf8-8692a7893d95', - 'navi.net':: 'arn:aws:acm:ap-south-1:492941056607:certificate/194e6d16-a263-4f08-bc2a-414e05bf5cd3', - 'naviinsurance.com':: 'arn:aws:acm:ap-south-1:492941056607:certificate/6e9dfccd-9794-483f-a884-789abf81747d', - }, - subnets:: { - internal: 'internal-lb-ap-south-1a.aps1.prod.navi-tech.in,internal-lb-ap-south-1b.aps1.prod.navi-tech.in,internal-lb-ap-south-1c.aps1.prod.navi-tech.in', - }, - accessLogBucket:: 'navi-prod-lb-access-logs', - accessLog:: true, - deletionProtection:: false, - }, - }, - }, - 'prod-3p':: self.default { - loadBalancer+:: { - fixedHostNames+:: { - 'mobile-application': 'api.navi.com', - }, - }, - }, - }, - - // GI cluster - - //PROD cluster - 'aps1.prod.navi-gi.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'gi', - }, - flinkBucket: 'navi-flink-gi-prod', - awsAccountId: 590617173486, - loadBalancer+: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:590617173486:regional/webacl/AclMASProdGi/284f5c83-ae37-4197-b885-37773aded948', - securityGroups+:: { - //This security group allows packets from everywhere - internetFacing:: 'sg-0b1ccba594a9d1119', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-09598b733e28af8f1', - - //This security group allows inter k8 cluster communication - internal:: 'sg-0c3570037bbe9e753', - - //This security group allows communication from nat gateways of prod cluster - natIp:: 'sg-0c13df2b692dadfbc', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-0c325908ef9db57da', - - // Cloudflare ips - cdn:: 'sg-0ecd8f0de802b40c2', - }, - sslCert:: { - 'prod.navi-gi.in':: 'arn:aws:acm:ap-south-1:590617173486:certificate/2ceb99d1-c50d-47d3-8e37-6743726fe48d', - 'prod.navi-gi-ext.com':: 'arn:aws:acm:ap-south-1:590617173486:certificate/2ceb99d1-c50d-47d3-8e37-6743726fe48d', - 'naviinsurance.com':: 'arn:aws:acm:ap-south-1:590617173486:certificate/b60efe78-e8da-43c0-ac7a-cb61adaffd43', - 'navi-gi.in':: 'arn:aws:acm:ap-south-1:590617173486:certificate/b60efe78-e8da-43c0-ac7a-cb61adaffd43', - 'navi.com':: 'arn:aws:acm:ap-south-1:590617173486:certificate/2ceb99d1-c50d-47d3-8e37-6743726fe48d', - 'argohealthsure.com':: 'arn:aws:acm:ap-south-1:590617173486:certificate/481cebc0-897f-48d2-88a7-9a1eccbfe793', - 'navi.net':: 'arn:aws:acm:ap-south-1:590617173486:certificate/904c0763-75ec-4c6c-8ac7-2094d72e778c', - - }, - subnets:: { - internal: 'ap-south-1a.aps1.prod.navi-gi.in,ap-south-1b.aps1.prod.navi-gi.in,ap-south-1c.aps1.prod.navi-gi.in', - }, - accessLogBucket:: 'navi-prod-gi-lb-access-logs', - accessLog:: true, - deletionProtection:: false, - }, - }, - }, - 'prod-3p':: self.default { - loadBalancer+:: { - fixedHostNames+:: { - 'mobile-application': 'gi-api.navi.com', - }, - }, - }, - }, - - 'aps1.prod.navi-amc.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'amc', - }, - zalandoEnabled:: false, - flinkBucket: 'navi-flink-navi-amc-prod', - awsAccountId: 121661608696, - isVpaDeployed:: true, - loadBalancer+: { - annotations+:: { - webAcl:: 'WAF ACL is not required for this cluster. Use API Gateway or Cloudflare instead.', - securityGroups+:: { - //This security group allows packets from everywhere - internetFacing:: 'sg-084e3d4a23b307840', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0ba9c0e4dbb8c1e09', - - //This security group allows inter k8 cluster communication - internal:: 'sg-064a66df84f58df82', - - //This security group allows communication from nat gateways of prod cluster - natIp:: 'sg-045b3038d61746065', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-0a0499ba0ce2a488f', - }, - sslCert:: { - 'prod.navi-amc.in':: 'arn:aws:acm:ap-south-1:121661608696:certificate/20378b6a-0391-43f0-bd59-6ac83ebf7d60', - }, - subnets:: { - internal: 'ap-south-1a.aps1.prod.navi-amc.in,ap-south-1b.aps1.prod.navi-amc.in,ap-south-1c.aps1.prod.navi-amc.in', - }, - accessLogBucket:: 'navi-prod-amc-lb-access-logs', - accessLog:: true, - }, - }, - }, - }, - - //colending PROD cluster - 'aps1.prod.navi-colending.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'colending', - }, - zalandoEnabled:: false, - loadBalancer+: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:903695743721:regional/webacl/AclMASProdColending/3c155013-3bd1-4198-b7fc-8d345acb2324', - securityGroups+:: { - //This security group allows packets from everywhere - internetFacing:: 'sg-030b62263df624188', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-03b488d79b9bf1d40', - - //This security group allows inter k8 cluster communication - internal:: 'sg-0e58f969aa60be012', - - //This security group allows communication from nat gateways of prod cluster - natIp:: 'sg-00020a1085c55a380', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-05a801a9dcdcaeff2', - }, - sslCert:: { - 'prod.navi-colending.in':: 'arn:aws:acm:ap-south-1:903695743721:certificate/821aa0ec-ecfa-4432-af60-718fe249aede', - 'go-nlc.com':: 'arn:aws:acm:ap-south-1:903695743721:certificate/2c8774fd-de94-47c9-96f5-377fcdd48c1c', - }, - subnets:: { - internal: 'prod-colending-private-subnet01-ap-south-1a,prod-colending-private-subnet01-ap-south-1b,prod-colending-private-subnet01-ap-south-1c', - }, - accessLogBucket:: 'aps1-prod-colending-alb-access-logs', - accessLog:: true, - deletionProtection:: false, - }, - }, - }, - 'prod-3p':: self.default { - loadBalancer+:: { - fixedHostNames+:: { - 'mobile-application': 'colending-api.navi.com', - }, - }, - }, - }, - //colending nonprod cluster - 'aps1.np.navi-colending.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'colending', - }, - zalandoEnabled:: false, - loadBalancer+: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:942894539187:regional/webacl/AclNonProdColending/fb72041b-1136-4d51-a3af-2f3510c71763', - securityGroups+:: { - //This security group allows packets from everywhere - internetFacing:: 'sg-0001aca7a784a21aa', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0367bbf59da32f056', - - //This security group allows inter k8 cluster communication - internal:: 'sg-01e48bdc4d14b4b71', - - //This security group allows communication from nat gateways of nonprod cluster - natIp:: 'sg-00e7c7c3ae689c0bb', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-07a6684a8c4caf18e', - }, - sslCert:: { - 'np.navi-colending.in':: 'arn:aws:acm:ap-south-1:942894539187:certificate/c0588d27-8375-4795-89a4-b417f9b92ee4', - }, - subnets:: { - internal: 'nonprod-colending-private-subnet01-ap-south-1a,nonprod-colending-private-subnet01-ap-south-1b,nonprod-colending-private-subnet01-ap-south-1c', - }, - accessLogBucket:: 'aps1-np-colending-alb-access-logs', - accessLog:: true, - deletionProtection:: false, - }, - }, - }, - qa:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-services-alb', - }, - }, - }, - dev:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-services-alb', - }, - }, - }, - 'qa-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-internal-services-alb', - }, - }, - }, - perf:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'perf-services-alb', - }, - }, - }, - 'dev-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-internal-services-alb', - }, - }, - }, - 'dev-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-critical-services-alb', - }, - }, - }, - 'qa-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-critical-services-alb', - }, - }, - }, - 'dev-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-3p-services-alb', - }, - }, - }, - 'qa-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-3p-services-alb', - }, - }, - }, - }, - - //navi-pay nonprod cluster - 'aps1.np.navi-pay.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'navi-pay', - }, - flinkBucket: 'navi-flink-navi-pay-nonprod', - awsAccountId: 840875920349, - zalandoEnabled:: false, - commonApiGateway+:: { - externalAuth:: { - config:: { - url:: 'https://dev-navipay-external-client.np.navi-pay.in/external-client-service/auth', - }, - }, - }, - loadBalancer+: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:840875920349:regional/webacl/AclNonProdNaviPay/4066d790-24db-420b-8bef-18fab8aab41e', - securityGroups+:: { - //This security group allows packets from everywhere - internetFacing:: 'sg-0fa070f1f06716bff', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0e3a4d99b08f1af52', - - //This security group allows inter k8 cluster communication - internal:: 'sg-08780f13445d3455d', - - //This security group allows communication from nat gateways of nonprod cluster - natIp:: 'sg-0eb39100171bbde83', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-08721320e6adbdf1b', - - // Cloudflare ips - cdn:: 'sg-04aa6cd49eed4a11d', - }, - sslCert:: { - 'np.navi-pay.in':: 'arn:aws:acm:ap-south-1:840875920349:certificate/9a655746-7db5-4c67-8941-22f0ff80026e', - }, - subnets:: { - internal: 'nonprod-navi-pay-private-subnet01-ap-south-1a,nonprod-navi-pay-private-subnet01-ap-south-1b,nonprod-navi-pay-private-subnet01-ap-south-1c', - }, - accessLogBucket:: 'aps1-np-navi-pay-alb-access-logs', - accessLog:: true, - deletionProtection:: false, - }, - }, - }, - qa:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-services-alb', - }, - }, - }, - dev:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-services-alb', - }, - }, - }, - 'qa-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-internal-services-alb', - }, - }, - }, - perf:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'perf-services-alb', - }, - }, - }, - 'dev-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-internal-services-alb', - }, - }, - }, - 'dev-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-critical-services-alb', - }, - }, - }, - 'qa-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-critical-services-alb', - }, - }, - }, - 'dev-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-3p-services-alb', - }, - }, - }, - 'qa-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-3p-services-alb', - }, - }, - }, - }, - - //navi-saas nonprod cluster - 'aps1.np.navi-saas.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'saas', - }, - zalandoEnabled:: false, - loadBalancer+: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:334573405453:regional/webacl/AclNonProdNaviSaas/8f6e2e84-9c90-4956-825c-4cff20a38e18', - securityGroups+:: { - //This security group allows packets from everywhere - internetFacing:: 'sg-0478f9870d4a9c560', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-02af9692b15baa4f3', - - //This security group allows inter k8 cluster communication - internal:: 'sg-0c9b05d1d251ad6a4', - - //This security group allows communication from nat gateways of nonprod cluster - natIp:: 'sg-0ba2f4125960ee4c9', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-00f43883eaa7a2ebb', - - // Cloudflare ips - cdn:: 'sg-0d8654c7f61d13b36', - }, - sslCert:: { - 'np.navi-saas.in':: 'arn:aws:acm:ap-south-1:334573405453:certificate/7dc303c8-2fd6-40c9-89fd-d85676e00f74', - }, - subnets:: { - internal: 'nonprod-navi-saas-private-subnet01-ap-south-1a,nonprod-navi-saas-private-subnet01-ap-south-1b,nonprod-navi-saas-private-subnet01-ap-south-1c', - }, - accessLogBucket:: 'aps1-np-navi-saas-alb-access-logs', - accessLog:: true, - deletionProtection:: false, - }, - }, - }, - qa:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-services-alb', - }, - }, - }, - dev:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-services-alb', - }, - }, - }, - 'qa-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-internal-services-alb', - }, - }, - }, - perf:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'perf-services-alb', - }, - }, - }, - 'dev-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-internal-services-alb', - }, - }, - }, - 'dev-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-critical-services-alb', - }, - }, - }, - 'qa-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-critical-services-alb', - }, - }, - }, - 'dev-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-3p-services-alb', - }, - }, - }, - 'qa-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-3p-services-alb', - }, - }, - }, - }, - - //Spike cluster - 'spike.np.navi-tech.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'shared', - }, - loadBalancer+:: { - annotations+:: { - webAcl:: 'arn:aws:wafv2:ap-south-1:571315076762:regional/webacl/AclNonProd/9ad3e612-4125-42ec-ab83-9e83ce95ac22', - securityGroups+:: { - //This security group allows packets from everywhere - internetFacing:: 'sg-0ebec8d9727618fd6', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0fd848902c4616550', - - //This security group allows inter k8 cluster communication - internal:: 'sg-009129cbe138c921a', - - // sg for http - http:: 'sg-06cc4240b0ffd8cc4', - - // sg for CF ips - cdn:: 'sg-0b7563d6b962d6676', - }, - sslCert:: { - 'spike.navi-tech.in':: 'arn:aws:acm:ap-south-1:571315076762:certificate/4cbea2e2-2a83-4733-a822-29f44a6a16c4', - 'spike.navi-ext.com':: 'arn:aws:acm:ap-south-1:571315076762:certificate/ccf17c74-a5eb-4470-9963-cff3c3296c97', - }, - accessLogBucket:: 'navi-nonprod-lb-access-logs', - deletionProtection:: false, - }, - }, - }, - }, - - //Data platform cluster - 'aps1.dp.navi-tech.in':: { - default:: $.baseCluster { - sidecarEnabled:: false, - additionalTags+:: { - product:: 'DataPlatform', - }, - flinkBucket: 'navi-flink-dp-prod', - awsAccountId: 594542361424, - isVpaDeployed:: false, - loadBalancer+:: { - annotations+:: { - webAcl:: 'WAF ACL is not required for this cluster. Use API Gateway or Cloudflare instead.', - securityGroups+:: { - - //This security group allows inter k8 cluster communication(nodes security group) - internal:: 'sg-07a65dbfbd6c42341', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-04b7d5863a360176c', - - //This security group allows packets from everywhere - internetFacing:: 'sg-0473a1399a9671143', - - natIp:: 'sg-0099e44dd1758ab89', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-03eaac3bc24db6738', - - // Cloudflare SG - cdn:: 'sg-0a3d26e45c4d32787', - }, - sslCert:: { - 'dp.navi-tech.in':: 'arn:aws:acm:ap-south-1:594542361424:certificate/3646fee2-c07a-4e43-9683-14edb14cf694', - 'prod.navi-tech.in':: 'arn:aws:acm:ap-south-1:492941056607:certificate/07a548dc-249d-4475-8783-58e3060b0c3f', - }, - accessLog:: true, - accessLogBucket:: 'aps1-dp-navi-tech-alb-access-logs', - subnets:: { - internal: 'data-platform-eks-private-ap-south-1a,data-platform-eks-private-ap-south-1b,data-platform-eks-private-ap-south-1c', - }, - }, - }, - }, - }, - //Data platform cluster - 'aps1.np.dp.navi-tech.in':: { - default:: $.baseCluster { - sidecarEnabled:: false, - additionalTags+:: { - product:: 'DataPlatform', - }, - flinkBucket: 'navi-flink-dp-nonprod', - awsAccountId: 644366753862, - isVpaDeployed:: false, - loadBalancer+:: { - annotations+:: { - webAcl:: 'WAF ACL is not required for this cluster. Use API Gateway or Cloudflare instead.', - securityGroups+:: { - - //This security group allows inter k8 cluster communication(nodes security group) - internal:: 'sg-0694dbac4b980a99c', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-05577e828628ad6fa', - - //This security group allows packets from everywhere - internetFacing:: 'sg-0bc67bbc16eeaa7fc', - - natIp:: 'sg-0b1c4e57f642bf766', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-00667a4f566c8ffc8', - - // Cloudflare SG - cdn:: 'sg-015f6617b95d8448f', - }, - sslCert:: { - 'np.dp.navi-tech.in':: 'arn:aws:acm:ap-south-1:644366753862:certificate/1033dabd-c5c8-4e45-aad1-380d53c1d232', - }, - accessLog:: true, - accessLogBucket:: 'aps1-np-dp-navi-tech-alb-access-logs', - subnets:: { - internal: 'data-platform-nonprod-private-subnet01-ap-south-1a,data-platform-nonprod-private-subnet01-ap-south-1b', - }, - }, - }, - }, - }, - - //Navi-pay prod cluster - 'aps1.prod.navi-pay.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'navi-pay', - }, - zalandoEnabled:: false, - flinkBucket: 'navi-flink-prod', - awsAccountId: 928489389470, - isVpaDeployed:: true, - loadBalancer+:: { - annotations+:: { - webAcl:: 'WAF ACL is not required for this cluster. Use API Gateway or Cloudflare instead.', - securityGroups+:: { - - //This security group allows inter k8 cluster communication(nodes security group) - internal:: 'sg-038b43e1ec70f8e8f', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-008cea2813bc422d0', - - //This security group allows packets from everywhere - internetFacing:: 'sg-06e5131b85ed91eb6', - - natIp:: 'sg-06476c7a084fc7994', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-0c4b2773323da9c66', - - // Cloudflare SG - cdn:: 'sg-0971dd662e54a5722', - }, - sslCert:: { - 'prod.navi-pay.in':: 'arn:aws:acm:ap-south-1:928489389470:certificate/4c2826e3-5f7d-4dd6-a279-3584ee15d8fb', - }, - accessLog:: true, - accessLogBucket:: 'aps1-prod-navi-pay-alb-access-logs', - subnets:: { - internal: 'prod-navi-pay-private-subnet01-ap-south-1a,prod-navi-pay-private-subnet01-ap-south-1b,prod-navi-pay-private-subnet01-ap-south-1c', - }, - }, - }, - }, - }, - - 'aps1.prod.ml.navi-tech.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'blizzard', - }, - flinkBucket: 'navi-flink-ml-prod', - heapDumpBucket: 'java-heap-dumps-ml-prod', - isEfsSupported: true, - isFsxSupported: true, - awsAccountId: 492941056607, - isVpaDeployed:: false, - loadBalancer+:: { - annotations+:: { - webAcl:: 'WAF ACL is not required for this cluster. Use API Gateway or Cloudflare instead.', - securityGroups+:: { - //This security group allows inter k8 cluster communication(nodes security group) - internal:: 'sg-05d9d3e66d55ed677', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0139d7eb8709a9fdc', - - //This security group allows packets from everywhere - internetFacing:: 'sg-0e0cca12102820a81', - - natIp:: 'sg-0efb731547402e4b2', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-0762245d9e914ceec', - - // Cloudflare SG - cdn:: 'sg-0d429839605004d55', - }, - sslCert:: { - 'prod.ml.navi-tech.in':: 'arn:aws:acm:ap-south-1:492941056607:certificate/6bca6bec-e70b-4557-9f06-c7c4ac731ea1', - 'prod.navi-tech.in':: 'arn:aws:acm:ap-south-1:492941056607:certificate/07a548dc-249d-4475-8783-58e3060b0c3f', - }, - accessLog:: true, - accessLogBucket:: 'aps1-prod-mlops-alb-access-logs', - subnets:: { - internal: 'prod-mlops-private-subnet01-ap-south-1a,prod-mlops-private-subnet01-ap-south-1b,prod-mlops-private-subnet01-ap-south-1c', - }, - }, - }, - zalandoEnabled:: false, - }, - }, - 'aps1.np.navi-ppl.in'::{ - default:: $.baseCluster { - additionalTags+:: { - product:: 'navi-ppl', - }, - flinkBucket: 'navi-flink-navi-ppl-nonprod', - awsAccountId: 471112764652, - zalandoEnabled:: false, - isVpaDeployed:: true, - loadBalancer+:: { - annotations+:: { - webAcl:: 'WAF ACL is not required for this cluster. Use API Gateway or Cloudflare instead.', - securityGroups+:: { - //This security group allows inter k8 cluster communication(nodes security group) - internal:: 'sg-0051cb11fff4c5fb2', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0be3e60ef8a431589', - - //This security group allows packets from everywhere - internetFacing:: 'sg-0a92ec85b904a120c', - - //This security group allows communication from nat gateways of nonprod cluster - natIp:: 'sg-0ad9b23a6bce01619', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-0be7aeae9826fdd35', - - // Cloudflare SG - cdn:: 'sg-0d45e72ff61d8dd53', - }, - sslCert:: { - 'np.navi-ppl.in':: 'arn:aws:acm:ap-south-1:471112764652:certificate/fd0e85af-3e19-4086-944a-3e12f3b91b31', - }, - accessLog:: true, - accessLogBucket:: 'aps1-np-navi-ppl-alb-access-logs', - subnets:: { - internal: 'nonprod-navi-ppl-private-subnet01-ap-south-1a,nonprod-navi-ppl-private-subnet01-ap-south-1b,nonprod-navi-ppl-private-subnet01-ap-south-1c', - }, - deletionProtection:: false, - }, - }, - }, - qa:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-services-alb', - }, - }, - }, - dev:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-services-alb', - }, - }, - }, - 'qa-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-internal-services-alb', - }, - }, - }, - perf:: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'perf-services-alb', - }, - }, - }, - 'dev-internal':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-internal-services-alb', - }, - }, - }, - 'dev-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-critical-services-alb', - }, - }, - }, - 'qa-critical':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-critical-services-alb', - }, - }, - }, - 'dev-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'dev-3p-services-alb', - }, - }, - }, - 'qa-3p':: self.default { - loadBalancer+:: { - annotations+:: { - alb:: 'qa-3p-services-alb', - }, - }, - }, - }, - 'aps1.prod.navi-ppl.in':: { - default:: $.baseCluster { - additionalTags+:: { - product:: 'navi-ppl', - }, - zalandoEnabled:: false, - flinkBucket: 'navi-flink-navi-ppl-prod', - awsAccountId: 471112770174, - isVpaDeployed:: true, - loadBalancer+:: { - annotations+:: { - webAcl:: 'WAF ACL is not required for this cluster. Use API Gateway or Cloudflare instead.', - securityGroups+:: { - - //This security group allows inter k8 cluster communication(nodes security group) - internal:: 'sg-0f938fdee0487d9cb', - - //This security group allows packets from office Ips(VPN, LAN etc) - officeIp:: 'sg-0b20b1e4d6bdaacd8', - - //This security group allows packets from everywhere - internetFacing:: 'sg-0d203187e4a7fde6f', - - natIp:: 'sg-0d6989b921d40fb98', - - //This security group allows HTTP traffic from everywhere - http:: 'sg-0e2b16c7bc3151f47', - - // Cloudflare SG - cdn:: 'sg-0dbefd59452817bc6', - }, - sslCert:: { - 'prod.navi-ppl.in':: 'arn:aws:acm:ap-south-1:471112770174:certificate/a9bacc24-150d-4725-a888-cdf340b15e60', - }, - accessLog:: true, - accessLogBucket:: 'aps1-prod-navi-ppl-alb-access-logs', - subnets:: { - internal: 'prod-navi-ppl-private-subnet01-ap-south-1a,prod-navi-ppl-private-subnet01-ap-south-1b,prod-navi-ppl-private-subnet01-ap-south-1c', - }, - }, - }, - }, - } -} diff --git a/templates/common.jsonnet b/templates/common.jsonnet deleted file mode 100644 index f895274a..00000000 --- a/templates/common.jsonnet +++ /dev/null @@ -1,67 +0,0 @@ -local chart = import 'chart.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local load_balancer_util = import 'load_balancer_util.jsonnet'; -local namespace_values = import 'namespace_values.jsonnet'; -local util = import 'util.jsonnet'; -local metadata = deployment_manifest.metadata; - -local remove_slash = function(key, value) - util.replace_character_in_string(metadata[key], '/', '_'); - -local metadata_without_slash = std.mapWithKey(remove_slash, metadata); - -local metadata_labels = { [field]: metadata_without_slash[field] for field in std.objectFields(metadata_without_slash) if field != 'product' }; -{ - labels:: - (if 'labels' in deployment_manifest then deployment_manifest.labels else {}) + - (metadata_labels) + - { - app: chart.service_name, - chart: chart.service_chart, - heritage: 'NaviDeploymentManifest', - release: deployment_manifest.name, - Team: deployment_manifest.team.name, - Environment: deployment_manifest.environment, - Name: deployment_manifest.name, - Product: if 'product' in metadata then metadata.product else namespace_values.additionalTags.product, - Owner: if deployment_manifest.infraVertical == 'lending' then 'medici' else if deployment_manifest.infraVertical == 'insurance' then 'gi' else deployment_manifest.infraVertical, - }, - - matchLabels:: - { - app: chart.service_name, - release: deployment_manifest.name, - }, - - awsTags:: { - app: deployment_manifest.name, - Environment: $.labels.Environment, - Team: $.labels.Team, - Name: $.labels.Name, - Owner: $.labels.Owner, - Product: $.labels.Product, - Namespace: deployment_manifest.deployment.namespace, - Ingress: load_balancer_util.alb_ingress_name(chart.full_service_name($.labels.Name)), - }, - - perfMockServerLabels:: $.labels { - release: deployment_manifest.deployment.name + '-mock-server', - Name: deployment_manifest.deployment.name + '-mock-server', - }, - - perfPostgresServerLabels:: $.labels { - release: deployment_manifest.deployment.name + '-postgres-server', - Name: deployment_manifest.deployment.name + '-postgres-server', - }, - - janitor_annotation:: { - 'janitor/ttl': deployment_manifest.metadata.ttl, - }, - - annotations_map:: { - perf: $.janitor_annotation, - sandbox: $.janitor_annotation, - }, - - annotations:: if deployment_manifest.environment in $.annotations_map then $.annotations_map[deployment_manifest.environment] else {}, -} diff --git a/templates/common_api_gateway.jsonnet b/templates/common_api_gateway.jsonnet deleted file mode 100644 index b668003c..00000000 --- a/templates/common_api_gateway.jsonnet +++ /dev/null @@ -1,213 +0,0 @@ -//Imports -local chart = import 'chart.jsonnet'; -local cluster_values = import 'cluster_values.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local load_balancer_util = import 'load_balancer_util.jsonnet'; -local namespace_values = import 'namespace_values.jsonnet'; -local port_map = import 'port_map.jsonnet'; -local util = import 'util.jsonnet'; -local deployment = deployment_manifest.deployment; - -local create_gateway_ingress(environment, servicePrefix, typeIdentifier, gateway, attributeIndex, serviceName) = { - local resourceName = '%s-%s-%s-%s' % [environment, servicePrefix, typeIdentifier, gateway.gatewayAttributes[attributeIndex].pathName], - local commonResourceName = '%s-%s-%s' % [environment, servicePrefix, gateway.gatewayAttributes[attributeIndex].pathName], - - local rateLimitIdentifier = '%s-%s-%s' % [environment, servicePrefix, typeIdentifier], - local pathName = if 'pathName' in gateway.gatewayAttributes[attributeIndex] then gateway.gatewayAttributes[attributeIndex].pathName, - - local urlRewritePlugin = if (std.objectHas(gateway.gatewayAttributes[attributeIndex], 'sourceGatewayPath')) - && (gateway.gatewayAttributes[attributeIndex].sourceGatewayPath != gateway.gatewayAttributes[attributeIndex].targetGatewayPath) - then commonResourceName + '-url-rewrite', - local externalAuthPlugin = if (std.objectHas(gateway.gatewayAttributes[attributeIndex], 'externalAuth') && typeIdentifier == 'external') - then (if gateway.gatewayAttributes[attributeIndex].externalAuth then resourceName + '-external-auth'), - local ipRestrictedPlugin = if (std.objectHas(gateway.gatewayAttributes[attributeIndex], 'whitelistedGatewayIps') && typeIdentifier == 'external') - then resourceName + '-ip-restriction', - local rateLimitRules = if 'rateLimitRules' in gateway.gatewayAttributes[attributeIndex] - then gateway.gatewayAttributes[attributeIndex].rateLimitRules else [], - local rateLimitPlugin = std.map(function(rule) - '%s-%s-%s-%s-%s' % [environment, servicePrefix, pathName, rule.name, 'rl'], - rateLimitRules), - - local kongPluginsList = [ - urlRewritePlugin, - ipRestrictedPlugin, - externalAuthPlugin, - (if typeIdentifier == 'external' then std.join(',', rateLimitPlugin)), - ], - local filteresKongPluginsList = std.filter(function(plugin) plugin != null && std.length(plugin) > 0, kongPluginsList), - - - apiVersion: 'networking.k8s.io/v1', - kind: 'Ingress', - metadata: { - name: resourceName, - labels: common.labels { - Name: resourceName, - 'gateway-resource-identifier': commonResourceName, - }, - annotations: common.annotations { - [if filteresKongPluginsList != null && std.length(filteresKongPluginsList) > 0 then 'konghq.com/plugins']: std.join(',', filteresKongPluginsList), - 'external-dns.alpha.kubernetes.io/exclude': 'true', - }, - namespace: deployment_manifest.deployment.namespace, - }, - spec: { - ingressClassName: 'kong-' + typeIdentifier, - rules: [ - { - host: if (typeIdentifier == 'external') then gateway.commonApiGatewayUrl else gateway.internalCommonApiGatewayUrl, - http: { - paths: [ - { - path: gateway.gatewayAttributes[attributeIndex].sourceGatewayPath, - pathType: 'ImplementationSpecific', - backend: { - service: { - name: serviceName, - port: { - number: port_map.getPort('serviceport'), - }, - }, - }, - }, - ], - }, - }, - ], - }, -}; - -// This will be a common resource across internal & external gateways -local create_gateway_url_plugin(environment, servicePrefix, gateway, attributeIndex, serviceName) = { - local resourceName = '%s-%s-%s' % [environment, servicePrefix, gateway.gatewayAttributes[attributeIndex].pathName], - apiVersion: 'configuration.konghq.com/v1', - kind: 'KongPlugin', - metadata: { - name: resourceName + '-url-rewrite', - labels: common.labels { - Name: resourceName + '-url-rewrite', - 'gateway-resource-identifier': resourceName, - }, - namespace: deployment_manifest.deployment.namespace, - }, - config: { - replace: { - uri: gateway.gatewayAttributes[attributeIndex].targetGatewayPath, - }, - }, - plugin: 'request-transformer', -}; - -local create_external_auth_plugin(environment, servicePrefix, typeIdentifier, gateway, attributeIndex, serviceName) = { - local resourceName = '%s-%s-%s-%s' % [environment, servicePrefix, typeIdentifier, gateway.gatewayAttributes[attributeIndex].pathName], - local commonResourceName = '%s-%s-%s' % [environment, servicePrefix, gateway.gatewayAttributes[attributeIndex].pathName], - local currentCluster = deployment_manifest.cluster, - local currentNamespace = deployment_manifest.deployment.namespace, - local configValues = cluster_values[deployment_manifest.cluster], - local configUrl = if currentNamespace in configValues - then configValues[currentNamespace].commonApiGateway.externalAuth.config.url - else configValues.default.commonApiGateway.externalAuth.config.url, - - apiVersion: 'configuration.konghq.com/v1', - kind: 'KongPlugin', - metadata: { - name: resourceName + '-external-auth', - labels: common.labels { - Name: resourceName + '-external-auth', - 'gateway-resource-identifier': resourceName, - }, - namespace: currentNamespace, - }, - config: { - url: configUrl, - }, - plugin: 'external-auth', -}; - -// This will only be required for External Gateway -local create_gateway_ip_plugin(environment, servicePrefix, typeIdentifier, gateway, attributeIndex, serviceName) = { - local resourceName = '%s-%s-%s-%s' % [environment, servicePrefix, typeIdentifier, gateway.gatewayAttributes[attributeIndex].pathName], - local commonResourceName = '%s-%s-%s' % [environment, servicePrefix, gateway.gatewayAttributes[attributeIndex].pathName], - apiVersion: 'configuration.konghq.com/v1', - kind: 'KongPlugin', - metadata: { - name: resourceName + '-ip-restriction', - labels: common.labels { - Name: resourceName + '-ip-restriction', - 'gateway-resource-identifier': commonResourceName, - }, - namespace: deployment_manifest.deployment.namespace, - }, - config: { - allow: std.split(std.strReplace(gateway.gatewayAttributes[attributeIndex].whitelistedGatewayIps, ' ', ''), ','), - }, - plugin: 'ip-restriction', -}; - -// This is only for external api gateways currently. -local create_kong_rate_limiter(environment, servicePrefix, typeIdentifier, gateway, attributeIndex, serviceName) = { - local resourceName = '%s-%s-%s' % [environment, servicePrefix, gateway.gatewayAttributes[attributeIndex].pathName], - local commonResourceName = '%s-%s-%s' % [environment, servicePrefix, gateway.gatewayAttributes[attributeIndex].pathName], - local forTheGateway = gateway.gatewayAttributes[attributeIndex].sourceGatewayPath, - local rateLimitRules = if 'rateLimitRules' in gateway.gatewayAttributes[attributeIndex] - then gateway.gatewayAttributes[attributeIndex].rateLimitRules else [], - - kongrules: [{ - apiVersion: 'configuration.konghq.com/v1', - kind: 'KongPlugin', - plugin: 'rate-limiting', - metadata: { - name: resourceName + '-%s' % rule.name + '-rl', // shortening due 63 character limits - labels: common.labels { - 'gateway-resource-identifier': resourceName, - }, - }, - config: { - minute: rule.limit, - limit_by: '%s' % rule.options, - [if rule.options == 'path' then 'path' else null]: '%s' % forTheGateway, - [if rule.options == 'header' then 'header_name' else null]: '%s' % rule.header, - }, - } for rule in rateLimitRules], -}; - -local gateways = deployment.commonApiGateways; -local gatewaysLen = std.length(deployment.commonApiGateways); - -std.map( - function(apiGatewayIndex) { - local gateway = gateways[apiGatewayIndex], - local serviceName = chart.full_service_name(deployment.name), - local servicePrefix = deployment.name, - local environment = deployment_manifest.environment, - local gatewayAttributeLen = std.length(gateway.gatewayAttributes), - local kongRateLimits = [ - create_kong_rate_limiter(environment, servicePrefix, 'external', gateway, attributeIndex, serviceName) - for attributeIndex in std.range(0, gatewayAttributeLen - 1) - if (std.objectHas(gateway.gatewayAttributes[attributeIndex], 'rateLimitRules')) - ], - - apiVersion: 'v1', - kind: 'List', - items: [create_gateway_ingress(environment, servicePrefix, 'external', gateway, attributeIndex, serviceName) for attributeIndex in std.range(0, gatewayAttributeLen - 1)] + - [create_gateway_ingress(environment, servicePrefix, 'internal', gateway, attributeIndex, serviceName) for attributeIndex in std.range(0, gatewayAttributeLen - 1)] + - [ - create_gateway_url_plugin(environment, servicePrefix, gateway, attributeIndex, serviceName) - for attributeIndex in std.range(0, gatewayAttributeLen - 1) - if (gateway.gatewayAttributes[attributeIndex].sourceGatewayPath != gateway.gatewayAttributes[attributeIndex].targetGatewayPath) - ] + - [ - create_gateway_ip_plugin(environment, servicePrefix, 'external', gateway, attributeIndex, serviceName) - for attributeIndex in std.range(0, gatewayAttributeLen - 1) - if (std.objectHas(gateway.gatewayAttributes[attributeIndex], 'whitelistedGatewayIps')) - ] + - [ - create_external_auth_plugin(environment, servicePrefix, 'external', gateway, attributeIndex, serviceName) - for attributeIndex in std.range(0, gatewayAttributeLen - 1) - if (gateway.gatewayAttributes[attributeIndex].externalAuth) - ] + - if (std.length(kongRateLimits) > 0) then kongRateLimits[0].kongrules else [], - }, - std.range(0, gatewaysLen - 1) -) diff --git a/templates/configmap.jsonnet b/templates/configmap.jsonnet deleted file mode 100644 index 096a7a54..00000000 --- a/templates/configmap.jsonnet +++ /dev/null @@ -1,20 +0,0 @@ -local chart = import 'chart.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local util = import 'util.jsonnet'; -local deployment = deployment_manifest.deployment; -local common = import 'common.jsonnet'; - -if 'environmentFile' in deployment then - local environmentFile = deployment.environmentFile; - { - apiVersion: 'v1', - data: { - [util.file_name(environmentFile.path)]: environmentFile.data, - }, - kind: 'ConfigMap', - metadata: { - name: chart.full_service_name(deployment_manifest.deployment.name) + '-cm', - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations, - }, - } diff --git a/templates/cron_hpa_autoscaler.jsonnet b/templates/cron_hpa_autoscaler.jsonnet deleted file mode 100644 index c73595f3..00000000 --- a/templates/cron_hpa_autoscaler.jsonnet +++ /dev/null @@ -1,34 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local util = import 'util.jsonnet'; -local vars = import 'vars.jsonnet'; - -local deployment = deployment_manifest.deployment; -local hpa = deployment_manifest.deployment.hpa; - -local isEnabled = hpa.type == vars.deployment.hpa.type.cron; -local basename = chart.full_service_name(deployment.name); - -local name = if isEnabled then - basename + '-cron-hpa-autoscaler' -else - basename + '-cron-hpa-autoscaler-disabled'; - - -if std.length(hpa.cronJobs) != 0 then { - - apiVersion: 'autoscaling.alibabacloud.com/v1beta1', - kind: 'CronHorizontalPodAutoscaler', - metadata: { - name: name, - labels: common.labels { 'controller-tools.k8s.io': '1.0' }, - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations, - }, - spec: { - scaleTargetRef: util.hpa_scale_target_ref(deployment.name, deployment.controller, !isEnabled), - deploymentName: chart.full_service_name(deployment_manifest.deployment.name), - jobs: [job + (if job.name == 'ScaleDown' then { targetSize: hpa.minReplicas } else { targetSize: hpa.maxReplicas }) for job in hpa.cronJobs], - }, -} diff --git a/templates/default_alerts.jsonnet b/templates/default_alerts.jsonnet deleted file mode 100644 index 8378deb4..00000000 --- a/templates/default_alerts.jsonnet +++ /dev/null @@ -1,407 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local namespace_values = import 'namespace_values.jsonnet'; -local app_name = chart.full_service_name(deployment_manifest.deployment.name); -local namespace = deployment_manifest.deployment.namespace; -local load_balancer_util = import 'load_balancer_util.jsonnet'; -local alerts = deployment_manifest.deployment.alerts; -local manifest_util = import 'manifest_util.jsonnet'; -local deployment = deployment_manifest.deployment; -local vars = import 'vars.jsonnet'; -local util = import 'util.jsonnet'; - -local isVpaEnabled = deployment_manifest.deployment.isVpaEnabled; -local environment = deployment_manifest.environment; - -local commonAlertFields = { - appName: common.awsTags.Name, - fullName: chart.full_service_name(deployment.name), - namespace: namespace, - environment: environment, -}; - -local loadBalancerAlertFields = commonAlertFields { - albIngressName: load_balancer_util.alb_ingress_name(app_name), -}; - -local databaseAlertFields = commonAlertFields { - dbInstance: deployment_manifest.extraResources.database.instanceName, -}; - -local baseLabels = function(alert) { - labels: { - severity: alert.severity, - alertTeam: deployment_manifest.team.name, - appName: app_name, - [if manifest_util.is_custom_slack_channel_enabled(alert) then 'slackChannel']: alert.slackChannel, - }, -}; - -local baseAnnotations = function(alert) { - annotations: { - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/509936863/Runbook', - }, -}; - -local mapAlerts(alertGroup, alerts) = std.filterMap( - function(alert) alert.type in alertGroup, - function(alert) baseAnnotations(alert) + alertGroup[alert.type](alert) + baseLabels(alert), - alerts -); - -local targetGroupAlerts = { - http4xx: function(alert) { - alert: 'HighHTTP4xx', - annotations+: { - description: '%(namespace)s/%(appName)s has more than %(threshold)s%% http 4xx errors in last %(duration)s' % (loadBalancerAlertFields { threshold: alert.threshold, duration: alert.duration }), - summary: 'Service is facing lot of http 4xx errors', - }, - expr: '((aws_alb_tg_httpcode_target_4_xx_count_sum{tag_Name=~"%(fullName)s",tag_Namespace="%(namespace)s"}/aws_alb_tg_request_count_sum{tag_Name=~"%(fullName)s",tag_Namespace="%(namespace)s"})*100) > %(threshold)s' % (loadBalancerAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - http5xx: function(alert) { - alert: 'HighHTTP5xx', - annotations+: { - description: '%(namespace)s/%(appName)s has more than %(threshold)s%% http 5xx errors in last %(duration)s' % (loadBalancerAlertFields { threshold: alert.threshold, duration: alert.duration }), - summary: 'Service is facing lot of http 5xx errors', - }, - expr: '((aws_alb_tg_httpcode_target_5_xx_count_sum{tag_Name=~"%(fullName)s",tag_Namespace="%(namespace)s"}/aws_alb_tg_request_count_sum{tag_Name=~"%(fullName)s",tag_Namespace="%(namespace)s"})*100) > %(threshold)s' % (loadBalancerAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - latency: function(alert) { - alert: 'HighHTTPLatency', - annotations+: { - description: '%(namespace)s/%(appName)s has latency higher than %(threshold)sms in last %(duration)s' % (loadBalancerAlertFields { threshold: alert.threshold, duration: alert.duration }), - summary: 'Service is having high latency', - }, - expr: '(aws_alb_tg_target_response_time_average{tag_Name=~"%(fullName)s",tag_Namespace="%(namespace)s"}) > %(threshold)s' % (loadBalancerAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, -}; - -/* -- TargetGroup will take default Name tag based on service name pass in ingress. -*/ - -local albAlerts = { - elb4xx: function(alert) { - alert: 'HighELB4xx', - annotations+: { - description: '%(namespace)s/%(appName)s has more than %(threshold)s%% elb 4xx errors in last %(duration)s' % (loadBalancerAlertFields { threshold: alert.threshold, duration: alert.duration }), - summary: 'Service is facing lot of elb 4xx errors', - }, - expr: '((sum by (tag_Ingress) (aws_alb_httpcode_elb_4_xx_count_sum{tag_Ingress="%(albIngressName)s"})/(sum by (tag_Ingress) (aws_alb_tg_request_count_sum{tag_Ingress="%(albIngressName)s"})))*100) > %(threshold)s' % (loadBalancerAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - elb5xx: function(alert) { - alert: 'HighELB5xx', - annotations+: { - description: '%(namespace)s/%(appName)s has more than %(threshold)s%% elb 5xx errors in last %(duration)s' % (loadBalancerAlertFields { threshold: alert.threshold, duration: alert.duration }), - summary: 'Service is facing lot of elb 5xx errors', - }, - expr: '((sum by (tag_Ingress) (aws_alb_httpcode_elb_5_xx_count_sum{tag_Ingress="%(albIngressName)s"})/(sum by (tag_Ingress) (aws_alb_tg_request_count_sum{tag_Ingress="%(albIngressName)s"})))*100) > %(threshold)s' % (loadBalancerAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, -}; - - -// Database alert -local databaseAlerts = { - highActiveConnection: function(alert) { - alert: 'HighActiveConnection', - annotations+: { - description: 'rds {{ $labels.server }} have high number of active connection {{ $value }}', - summary: 'High Active Connections', - }, - expr: '(sum(pg_stat_database_active_connection{server=~"%(dbInstance)s\\\\..*"}) by(server) / on (server) pg_params_max_connections) * 100 > %(threshold)s' % (databaseAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - provisionedCPUNotEnough: function(alert) { - alert: 'ProvisionedCPUNotEnough', - annotations+: { - description: 'rds {{ $labels.server }} have dip in cpu credit balance {{ $value }}', - summary: 'Fall in CPU credit balance', - }, - expr: 'delta(aws_rds_cpucredit_balance_minimum{dimension_DBInstanceIdentifier=~"%(dbInstance)s\\\\..*"}[10m]) < %(threshold)s' % (databaseAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - provisionedDiskNotEnough: function(alert) { - alert: 'DBProvisionedDiskNotEnough', - annotations+: { - description: 'rds {{ $labels.server }} have dip in burst balance {{ $value }}', - summary: 'Fall in EBS burst balance', - }, - expr: 'delta(aws_rds_burst_balance_minimum{dimension_DBInstanceIdentifier=~"%(dbInstance)s\\\\..*"}[10m]) < %(threshold)s' % (databaseAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - connectionAcquireTimeIsHigh: function(alert) { - alert: 'DBConnectionAcquireTimeIsHigh', - annotations+: { - description: 'Namespace: %(appName)s, AppName: %(namespace)s; Acquiring a DB connection for pod {{ $labels.pod }} took more than %(threshold)ss' % (databaseAlertFields { threshold: alert.threshold }), - summary: 'Container is taking too long to connect to database', - }, - expr: 'hikaricp_connections_acquire_seconds_max{pod=~"%(appName)s-.*",namespace="%(namespace)s"} > %(threshold)s AND on(pod,namespace) ((time() - kube_pod_created) >600)' % (databaseAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - maxConnectionPoolReached: function(alert) { - alert: 'MaxDBConnectionPoolReached', - annotations+: { - description: 'Namespace: %(namespace)s, AppName: %(appName)s; All connection in connection pool for pod {{ $labels.pod }} are used since %(duration)s' % (databaseAlertFields { duration: alert.duration }), - summary: 'All connections in hikari connection pool are used', - }, - expr: 'hikaricp_connections_active{pod=~"%(appName)s-.*",namespace="%(namespace)s"} / hikaricp_connections_max{pod=~"%(appName)s-.*",namespace="%(namespace)s"} == %(threshold)s' % (databaseAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - rdsCPUUnderUtilised: function(alert) { - alert: 'RdsCPUUnderUtilised', - annotations+: { - description: 'Namespace: %(namespace)s , AppName: %(appName)s; RDS utilised is below benchmark for last one week, consider downscaling. threshold: %(threshold)s percent' % (databaseAlertFields { threshold: alert.threshold }), - summary: 'RDS utilised is below benchmark for last one week', - }, - expr: '(weekly_rds_cpu_usage_average:dimension_DBInstanceIdentifier:labels{dimension_DBInstanceIdentifier=~"%(dbInstance)s.*"} < bool %(threshold)s ) >0' % (databaseAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, -}; - -local underUtilisedResourcesAlerts = { - k8sCpuUnderUtilised: function(alert) { - alert: 'K8sCpuUnderUtilised', - annotations+: { - description: 'Namespace: %(namespace)s , AppName: %(appName)s; K8s utilised is below benchmark for last one week, consider downscaling. threshold: %(threshold)s percent ' % (databaseAlertFields { threshold: alert.threshold }), - summary: 'K8S utilised is below benchmark for last one week', - }, - expr: 'max_over_time(container_cpu_usage_percentage:1h:container:namespace{namespace="%(namespace)s", container =~"%(appName)s.*"}[1w]) < %(threshold)s ' % (databaseAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - k8sMemoryUnderUtilised: function(alert) { - alert: 'K8sMemoryUnderUtilised', - annotations+: { - description: 'Namespace: %(namespace)s , AppName: %(appName)s; K8s utilised is below benchmark for last one week, consider downscaling. threshold: %(threshold)s percent' % (databaseAlertFields { threshold: alert.threshold }), - summary: 'K8S utilised is below benchmark for last one week', - }, - expr: '(container_memory_usage_percentage:1w:container:namespace{namespace="%(namespace)s", container =~"%(appName)s.*"} ) < %(threshold)s ' % (databaseAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - -}; - - -local kafkaAlerts = { - consumerGroupLag: function(alert) { - alert: 'HighConsumerGroupLag', - annotations+: { - description: '%(group)s has more than %(threshold)s lag in last %(duration)s' % ({ group: alert.group, threshold: alert.threshold, duration: alert.duration }), - summary: 'High consumergroup lag', - }, - expr: 'sum(kafka_consumergroup_lag{topic=~"%(topic)s",consumergroup=~"%(group)s"}) > %(threshold)s' % ({ group: alert.group, threshold: alert.threshold, topic: alert.topic }), - 'for': alert.duration, - }, - kafkaMessageRate: function(alert) { - alert: 'kafkaMessageRate', - annotations+: { - description: '%(topic)s has more than %(threshold)s message in last %(duration)s' % ({ topic: alert.topic, threshold: alert.threshold, duration: alert.duration }), - summary: 'High Message Rate', - }, - expr: 'sum(increase(kafka_topic_partition_current_offset{topic=~"%(topic)s"}[10m])) > %(threshold)s' % ({ threshold: alert.threshold, topic: alert.topic }), - 'for': alert.duration, - }, -}; - -//Custom Alerts -local customAlerts = { - custom: function(alert) { - alert: alert.name, - annotations+: { - description: 'Namespace:%s; App:%s; ' % [namespace, app_name] + alert.description, - summary: alert.summary, - }, - [if alert.duration != null then 'for']: alert.duration, - expr: alert.expression, - }, -}; - -//Custom RecordingRules -local recordingRulesForm = { - prometheusRecordingRule: function(alert) { - name: '%s' % [alert.name], - interval: '%s' % [alert.duration], - rules: [ - { - record: '%s' % [alert.record], - expr: '%s' % [alert.expression], - }, - ], - }, -}; - -local kongAlerts = { - kong4xx: function(alert) { - alert: 'Kong4xx', - annotations+: { - description: '{{ $labels.exported_service }} URI path has more than %(threshold)s%% http 4xx errors per minute for last %(duration)s' % (loadBalancerAlertFields { threshold: alert.threshold, duration: alert.duration }), - summary: 'One of the URI path in Kong API gateway is facing lot of http 4xx errors', - }, - expr: '((sum by (exported_service) (increase(kong_http_requests_total{exported_service=~".*%(appName)s.*", code=~"4.*"}[1m])) / sum by (exported_service) (increase(kong_http_requests_total{exported_service=~".*%(appName)s.*"}[1m]))) * 100) > %(threshold)s' % (loadBalancerAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - kong5xx: function(alert) { - alert: 'Kong5xx', - annotations+: { - description: '{{ $labels.exported_service }} URI path has more than %(threshold)s%% http 5xx errors per minute for last %(duration)s' % (loadBalancerAlertFields { threshold: alert.threshold, duration: alert.duration }), - summary: 'One of the URI path in Kong API gateway is facing lot of http 5xx errors', - }, - expr: '((sum by (exported_service) (increase(kong_http_requests_total{exported_service=~".*%(appName)s.*", code=~"5.*"}[1m])) / sum by (exported_service) (increase(kong_http_requests_total{exported_service=~".*%(appName)s.*"}[1m]))) * 100) > %(threshold)s' % (loadBalancerAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, - kongLatency: function(alert) { - alert: 'KongLatency', - annotations+: { - description: '{{ $labels.exported_service }} URI path has a 5 minute average latency higher than %(threshold)sms for last %(duration)s' % (loadBalancerAlertFields { threshold: alert.threshold, duration: alert.duration }), - summary: 'One of the URI path in Kong API gateway has 5 minute average high latency', - }, - expr: '(sum by (exported_service) (rate(kong_kong_latency_ms_sum{exported_service=~".*%(appName)s.*"}[5m]) / rate(kong_kong_latency_ms_count{exported_service=~".*%(appName)s.*"}[5m]))) > %(threshold)s' % (loadBalancerAlertFields { threshold: alert.threshold }), - 'for': alert.duration, - }, -}; - -local podAlerts = { - HighPodRestarts: function(alert) { - alert: 'HighPodRestarts', - annotations: { - description: 'Namespace: %s, AppName: %s; Pod restarted multiple times' % [namespace, app_name], - summary: 'High Pod Restarts', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: 'sum(increase(kube_pod_container_status_restarts_total{namespace="%s", pod=~"%s.*"}[%s])) > %s' % [namespace, app_name, alert.duration, alert.threshold], - }, - HighPodFailures: function(alert) { - alert: 'HighPodFailures', - annotations: { - description: 'Namespace: %s, AppName: %s; Pods were last terminated due to reason {{ $labels.reason }}' % [namespace, app_name], - summary: 'High Pod Failures', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: 'sum(increase(kube_pod_container_status_last_terminated_reason{namespace="%s", container=~"%s.*",reason !~ "Completed|Evicted|OOMKilled"}[%s])) by (reason,pod) > %s' % [namespace, app_name, alert.duration, alert.threshold], - }, - FrequentPodOOMKilled: function(alert) { - alert: 'FrequentPodOOMKilled', - annotations: { - description: 'Namespace: %s, AppName: %s; Pod: {{ $labels.pod }} is restarting multiple times because of OOMKilled' % [namespace, app_name], - summary: 'High Pod Failures', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: 'increase(kube_pod_container_status_restarts_total{namespace="%s", container="%s"}[%s]) >= %s AND ignoring(reason) kube_pod_container_status_last_terminated_reason{namespace="%s", container="%s", reason="OOMKilled"} > 0' % [namespace, app_name, alert.duration, alert.threshold, namespace, app_name], - }, - PodOOMKilled: function(alert) { - alert: 'PodOOMKilled', - annotations: { - description: 'Namespace: %s, AppName: %s; Pod: {{ $labels.pod }} killed because of OOMKilled' % [namespace, app_name], - summary: 'Pod OOMKilled', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: 'kube_pod_container_status_restarts_total{namespace="%s", container="%s"} - kube_pod_container_status_restarts_total{namespace="%s", container="%s"} offset %s >= %s AND ignoring(reason) kube_pod_container_status_last_terminated_reason{namespace="%s", container="%s", reason="OOMKilled"} > 0' % [namespace, app_name, namespace, app_name, alert.duration, alert.threshold, namespace, app_name], - }, - KubeContainerWaiting: function(alert) { - alert: 'KubeContainerWaiting', - annotations: { - description: 'Namespace: %s, AppName: %s; container in waiting state for one hour' % [namespace, app_name], - summary: 'container is waiting for too long', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: 'sum by (namespace, pod, container) (kube_pod_container_status_waiting_reason{container="%s", namespace="%s"}) > %s' % [app_name, namespace, alert.threshold], - 'for': alert.duration, - }, -}; - - -local mapRecordingRule(alertGroup, alerts) = std.filterMap( - function(alert) alert.type in alertGroup, - function(alert) alertGroup[alert.type](alert), - alerts -); - -local vpaAlerts(appName, namespace, teamName) = - (if isVpaEnabled then [ - { - alert: 'VPAUncappedTargetGreaterThanCappedTarget', - annotations: { - description: 'Uncapped target is more than bounds Namespace:%s; App:%s; ' % [namespace, app_name], - summary: 'Uncapped target is more than bounds, this means your service is requires lot more resources than what node may have', - }, - labels: { - severity: 'warning', - alertTeam: teamName, - appName: app_name, - }, - 'for': '1m', - expr: 'kube_verticalpodautoscaler_status_recommendation_containerrecommendations_uncappedtarget{container="%s"} / kube_verticalpodautoscaler_status_recommendation_containerrecommendations_target{container="%s"} > 1' % [appName, appName], - }, - ] else []); - -if !util.is_sandbox(environment) then { - apiVersion: 'monitoring.coreos.com/v1', - kind: 'PrometheusRule', - metadata: { - labels: common.labels { - prometheus: 'kube-prometheus', - role: 'alert-rules', - }, - name: app_name, - namespace: namespace, - annotations: common.annotations, - }, - spec: { - groups: [ - { - name: '%s-basic' % [app_name], - rules: (mapAlerts(podAlerts, alerts.pod)) - + (if manifest_util.is_database_present(deployment_manifest) then [ - { - alert: 'CriticalFreeDiskSpace', - annotations: { - description: 'rds {{ $labels.identifier }} have disk space less than {{ $value }}% and disk space autoscaling have reached the allowed limit.', - summary: 'Critical free disk space', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/269844543/Act+on+DB+alert#CriticalFreeDiskSpace', - }, - expr: '(aws_rds_free_storage_space_average{dimension_DBInstanceIdentifier=~"%(dbInstance)s"}/(1024*1024*1024)/ on () rds_config_AllocatedStorage{identifier=~"%(dbInstance)s"})*100 < 10 And on() (rds_config_AllocatedStorage{identifier=~"%(dbInstance)s"} / rds_config_MaxAllocatedStorage{identifier=~"%(dbInstance)s"}) > 0.9 ' % (databaseAlertFields), - 'for': '5m', - labels: { - severity: 'critical', - alertTeam: deployment_manifest.team.name, - appName: app_name, - }, - }, - ] else []) + (if (deployment.controller == vars.defaultController) then [ - { - alert: 'ReplicaUnavailableAlert', - annotations: { - description: 'Namespace: %s, AppName: %s; Not enough instances available since past 15m' % [namespace, app_name], - summary: 'Low desired replica count', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: '(kube_deployment_status_replicas_available{deployment="%s", namespace="%s"}) - ignoring(poddisruptionbudget, deployment) (kube_poddisruptionbudget_status_desired_healthy{poddisruptionbudget="%s-pdb",namespace="%s"}) < 0' % [app_name, namespace, app_name, namespace], - 'for': if deployment_manifest.team.name == 'DataScience' then '30m' else '15m', - labels: { - severity: 'critical', - alertTeam: deployment_manifest.team.name, - appName: app_name, - }, - }, - ] else []) - + (if load_balancer_util.is_using_tg(deployment_manifest.deployment.loadBalancers) then - mapAlerts(targetGroupAlerts, alerts.loadBalancer) else []) - + (if load_balancer_util.is_using_lb(deployment_manifest.deployment.loadBalancers, 'alb') then - mapAlerts(albAlerts, alerts.loadBalancer) else []) - + (if load_balancer_util.is_using_lb(deployment_manifest.deployment.loadBalancers, 'commonApiGateway') then - mapAlerts(kongAlerts, alerts.kong) else []) - + (if manifest_util.is_database_present(deployment_manifest) then - mapAlerts(databaseAlerts, alerts.database) else []) - + mapAlerts(kafkaAlerts, alerts.kafka) - + mapAlerts(customAlerts, alerts.custom) - + mapAlerts(underUtilisedResourcesAlerts, alerts.underUtilisedResources) - + vpaAlerts(app_name, namespace, deployment_manifest.team.name), - }, - ] + mapRecordingRule(recordingRulesForm, alerts.prometheusRecordingRule), - }, -} diff --git a/templates/deployment.jsonnet b/templates/deployment.jsonnet deleted file mode 100644 index 0584984d..00000000 --- a/templates/deployment.jsonnet +++ /dev/null @@ -1,29 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment_util = import 'deployment_util.jsonnet'; -local pod_template = import 'pod_template.jsonnet'; -local vars = import 'vars.jsonnet'; -local deployment = deployment_manifest.deployment; - - -if (deployment.controller == vars.defaultController) then { - apiVersion: 'apps/v1', - kind: 'Deployment', - metadata: { - name: chart.full_service_name(deployment.name), - labels: common.labels { - linkConfig: std.toString(deployment_manifest.deployment.isLinkConfig), - }, - annotations: common.annotations, - namespace: deployment_manifest.deployment.namespace, - }, - spec: { - progressDeadlineSeconds: deployment.progressDeadlineSeconds, - selector: { - matchLabels: common.matchLabels, - }, - strategy: deployment_util.strategy.rollingUpdate(), - template: pod_template, - }, -} diff --git a/templates/deployment_manifest.jsonnet b/templates/deployment_manifest.jsonnet deleted file mode 100644 index 5295dbba..00000000 --- a/templates/deployment_manifest.jsonnet +++ /dev/null @@ -1,209 +0,0 @@ -local deployment_manifest_json = import 'deployment_manifest.json'; -local health_check_values = import 'health_check_values.jsonnet'; -local manifest_util = import 'manifest_util.jsonnet'; -local port_map = import 'port_map.jsonnet'; -local probe_values = import 'probe_values.jsonnet'; -local default_service_port = [{ name: 'serviceport', port: 8080, enableGrpc: false }]; -local namespace_values = import 'namespace_values.jsonnet'; -local vars = import 'vars.jsonnet'; -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; - -local alertTypes(alerts) = std.map(function(alert) alert.type, alerts); -local containsAlertType(alerts, type) = if (std.find(type, alertTypes(alerts)) != []) then true else false; -local mergePodAlerts(defaultAlerts, manifestAlerts) = manifestAlerts + std.filter(function(alert) !containsAlertType(manifestAlerts, alert.type), defaultAlerts); -local deployment = deployment_manifest_json.deployment; -local defaultStartupProbe = health_check_values.getDefaultStartupProbe; -local defaultLivenessCheck = health_check_values.getDefaultLivenessCheck; -local defaultReadinessCheck = health_check_values.getDefaultReadinessCheck; -local esImageMapping = { - '7.17.0': vars.esImage_7_17_0, - '8.12.2': vars.esImage_8_12_2, -}; -local kibanaImageMapping = { - '7.17.0': vars.kibanaImage_7_17_0, - '8.12.2': vars.kibanaImage_8_12_2, - }; -local lbFunction = function(lbObject) { - type: if 'type' in lbObject then lbObject.type else error 'Missing loadbalancer type', - endpoint: if 'endpoint' in lbObject then lbObject.endpoint else null, - name: if 'name' in lbObject then lbObject.name else null, - groupName: if 'groupName' in lbObject then lbObject.groupName else null, - stickiness: if 'stickiness' in lbObject then lbObject.stickiness else false, - 'tls-1-1': if 'tls-1-1' in lbObject then lbObject['tls-1-1'] else false, - enableGrpc: if 'enableGrpc' in lbObject then lbObject.enableGrpc else false, - stickinessCookieDuration: if 'stickinessCookieDuration' in lbObject then lbObject.stickinessCookieDuration else 86400, - idleTimeout: if 'idleTimeout' in lbObject then lbObject.idleTimeout else 60, - slowStartDuration: if 'slowStartDuration' in lbObject then lbObject.slowStartDuration else 0, - accessPolicies: if 'accessPolicies' in lbObject then lbObject.accessPolicies else [], - extraSecurityGroups: if 'extraSecurityGroups' in lbObject then lbObject.extraSecurityGroups else [], - accessLog: if 'accessLog' in lbObject then lbObject.accessLog else namespace_values.loadBalancer.annotations.accessLog, - webAcl: if 'webAcl' in lbObject then lbObject.webAcl else namespace_values.loadBalancer.annotations.webAcl, - groupOrder: if 'groupOrder' in lbObject then lbObject.groupOrder else '100', - additionalEndpoints: if 'additionalEndpoints' in lbObject then lbObject.additionalEndpoints else [], - redirects: if 'redirects' in lbObject then lbObject.redirects else [], - exposeToLoadBalancer: false, -}; - -// A mixin that carefully overrides values. It should resemble deployment_manifest.json -local manifest_defaults = { - environment: if 'environment' in super then super.environment else null, - securityGroup: if 'securityGroup' in super then super.securityGroup else null, - metadata: if 'metadata' in super then super.metadata else {}, - sandboxParams: if 'sandboxParams' in super then super.sandboxParams else null, - [if 'flink' in deployment_manifest_json then 'flink' else null]+: { - loadBalancers: std.map(lbFunction, - if ('loadBalancers' in deployment_manifest_json.flink && deployment_manifest_json.flink.loadBalancers != []) then deployment_manifest_json.flink.loadBalancers else [{ type: 'none' }]), - }, - deployment+: { - //TODO: Just support $.name instead of $.deployment.name once all apps have migrated - name: if 'name' in super then super.name else $.name, - image: if 'image' in super then deployment.image else null, - imagePullPolicy: if 'imagePullPolicy' in super then deployment.imagePullPolicy else 'IfNotPresent', - maxSurge: if 'maxSurge' in super then deployment.maxSurge else null, - controller: if 'controller' in super then deployment.controller else vars.defaultController, - strategy: if 'strategy' in super then deployment.strategy else null, - strategyConfig: if 'strategyConfig' in super then deployment.strategyConfig else {}, - exposedPorts: if 'exposedPorts' in super then (if port_map.hasPort(super.exposedPorts, 'serviceport') then super.exposedPorts else super.exposedPorts + default_service_port) else default_service_port, - healthChecks+: { - startupProbeEnabled: if 'startupProbeEnabled' in super then deployment.healthChecks.startupProbeEnabled else false, - startupProbe+: { - type: $.deployment.healthChecks.livenessCheck.type, - port: $.deployment.healthChecks.livenessCheck.port, - path: $.deployment.healthChecks.livenessCheck.path, - successThreshold: defaultStartupProbe.successThreshold, - initialDelaySeconds: defaultStartupProbe.initialDelaySeconds, - periodSeconds: defaultStartupProbe.periodSeconds, - failureThreshold: defaultStartupProbe.failureThreshold, - httpHeaders+: $.deployment.healthChecks.livenessCheck.httpHeaders, - }, - livenessCheck+: { - type: if 'type' in super then super.type else defaultLivenessCheck.type, - port: if 'port' in super then super.port else defaultLivenessCheck.port, - path: if 'path' in super then super.path else defaultLivenessCheck.path, - successThreshold: if 'successThreshold' in super then super.successThreshold else defaultLivenessCheck.successThreshold, - initialDelaySeconds: if $.deployment.healthChecks.startupProbeEnabled then 0 else (if 'initialDelaySeconds' in super then super.initialDelaySeconds else defaultLivenessCheck.initialDelaySeconds), - periodSeconds: if 'periodSeconds' in super then super.periodSeconds else defaultLivenessCheck.periodSeconds, - failureThreshold: if 'failureThreshold' in super then super.failureThreshold else defaultLivenessCheck.failureThreshold, - httpHeaders+: if 'httpHeaders' in super then super.httpHeaders else defaultLivenessCheck.httpHeaders, - }, - readinessCheck+: { - type: if 'type' in super then super.type else defaultReadinessCheck.type, - port: if 'port' in super then super.port else defaultReadinessCheck.port, - path: if 'path' in super then super.path else defaultReadinessCheck.path, - successThreshold: if 'successThreshold' in super then super.successThreshold else defaultReadinessCheck.successThreshold, - initialDelaySeconds: if $.deployment.healthChecks.startupProbeEnabled then 0 else (if 'initialDelaySeconds' in super then super.initialDelaySeconds else defaultReadinessCheck.initialDelaySeconds), - periodSeconds: if 'periodSeconds' in super then super.periodSeconds else defaultReadinessCheck.periodSeconds, - failureThreshold: if 'failureThreshold' in super then super.failureThreshold else defaultReadinessCheck.failureThreshold, - httpHeaders+: if 'httpHeaders' in super then super.httpHeaders else defaultReadinessCheck.httpHeaders, - }, - }, - progressDeadlineSeconds: if 'timeout' in super then super.timeout else (if $.environment != vars.environments.prod then 720 else 540), - terminationGracePeriodSeconds: if 'terminationGracePeriodSeconds' in super then super.terminationGracePeriodSeconds else (if $.environment != vars.environments.prod then 60 else 90), - instance+: { - count: if 'count' in super then super.count else 2, - cpu: if 'cpu' in super then super.cpu else '0.25', - memory: if 'memory' in super then super.memory else '300Mi', - [if $.deployment.isVpaEnabled then 'minCPU']: if 'minCPU' in super then super.minCPU else 0.5, - [if $.deployment.isVpaEnabled then 'minMemory']: if 'minMemory' in super then super.minMemory else '512Mi', - gpu: if 'gpu' in super then super.gpu else 0, - gpuNodeSelector: if 'gpuNodeSelector' in super then super.gpuNodeSelector else { 'nvidia.com/gpu': 'true' }, - gpuTolerations: if 'gpuTolerations' in super then super.gpuTolerations else [{ effect: 'NoSchedule', key: 'nvidia.com/gpu', operator: 'Exists' }], - }, - environmentVariables+: [], - mountSecrets+: [], - namespace: if 'namespace' in super then super.namespace else 'default', - loadBalancers: std.map(lbFunction, - if ( 'loadBalancers' in super && super.loadBalancers != []) then super.loadBalancers else [{ type: 'none' }]), - commonApiGateways: std.map(function(apiGateways) { - commonApiGatewayUrl: if 'commonApiGatewayUrl' in apiGateways then apiGateways.commonApiGatewayUrl else null, - internalCommonApiGatewayUrl: if 'internalCommonApiGatewayUrl' in apiGateways then apiGateways.internalCommonApiGatewayUrl else null, - gatewayAttributes: if 'gatewayAttributes' in apiGateways then apiGateways.gatewayAttributes else [], - }, if ( 'commonApiGateways' in super && super.commonApiGateways != []) then super.commonApiGateways else [{ type: 'none' }]), - serviceMonitor+: { - enabled: if 'enabled' in super then super.enabled else false, - port: if 'port' in super then super.port else 'serviceport', - path: if 'path' in super then super.path else '/actuator/prometheus', - namespace: if 'namespace' in super then super.namespace else 'monitoring', - interval: if 'interval' in super then super.interval else '30s', - metricRelabelings: if 'metricRelabelings' in super then super.metricRelabelings else [], - scrapeTimeout: if 'scrapeTimeout' in super then super.scrapeTimeout else '10s', - }, - elasticSearch+: { - local defaultLabelPrefix = deployment.elasticSearch.instance.instanceName, - local elasticsearchVersion = if 'esVersion' in deployment.elasticSearch.instance then deployment.elasticSearch.instance.esVersion else '7.17.0', - enabled: if 'enabled' in super then super.enabled else false, - esLabels: if 'esLabels' in super then super.esLabels else { app: chart.service_name, chart: chart.service_chart, heritage: 'NaviDeploymentManifest', release: defaultLabelPrefix + '-elasticsearch', Team: deployment_manifest_json.team.name, Environment: deployment_manifest_json.environment, Name: defaultLabelPrefix + '-elasticsearch', Product: namespace_values.additionalTags.product, Owner: if deployment_manifest_json.infraVertical == 'lending' then 'medici' else if deployment_manifest_json.infraVertical == 'insurance' then 'gi' else deployment_manifest_json.infraVertical }, - instanceName: if 'instanceName' in super then super.instanceName else 'default-elasticsearch', - cpu: if 'cpu' in super then super.cpu else '1', - memory: if 'memory' in super then super.memory else '1Gi', - diskSpace: if 'diskSpace' in super then super.diskSpace else '30Gi', - esVersion: elasticsearchVersion, - esImage: esImageMapping[elasticsearchVersion], - esCount: if 'esCount' in super then super.esCount else 3, - esNodeSelector: if 'esNodeSelector' in super then super.esNodeSelector else { 'kops.k8s.io/instancegroup': 'datastore-nodes-1' }, - esTolerations: if 'esTolerations' in super then super.esTolerations else [{ effect: 'NoSchedule', key: 'node', operator: 'Equal', value: 'datastore' }], - kibana: if 'kibana' in super then super.kibana else null, - kibanaLabels: if 'kibanaLabels' in super then super.kibanaLabels else { app: chart.service_name, chart: chart.service_chart, heritage: 'NaviDeploymentManifest', release: defaultLabelPrefix + '-kibana', Team: deployment_manifest_json.team.name, Environment: deployment_manifest_json.environment, Name: defaultLabelPrefix + '-kibana', Product: namespace_values.additionalTags.product, Owner: if deployment_manifest_json.infraVertical == 'lending' then 'medici' else if deployment_manifest_json.infraVertical == 'insurance' then 'gi' else deployment_manifest_json.infraVertical }, - kibanaVersion: elasticsearchVersion, - kibanaImage: kibanaImageMapping[elasticsearchVersion], - }, - perfUtility+: { - mockServerEnabled: if 'mockServer' in super then super.mockServer else false, - mockServerImage: if 'mockServerImage' in super then super.mockServerImage else '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/perf-mock-server:latest', - postgresServerEnabled: if 'postgresServer' in super then super.postgresServer else false, - postgresServerImage: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/postgres:13', - }, - hpa+: { - type: if 'type' in super then super.type else vars.deployment.hpa.type.metrics, - maxReplicas: if 'maxReplicas' in super then super.maxReplicas else $.deployment.instance.count, - minReplicas: if 'minReplicas' in super then super.minReplicas else $.deployment.instance.count, - metrics: if 'metrics' in super then super.metrics else [], - custom_metrics: if 'custom_metrics' in super then super.custom_metrics else [], - cronJobs: if 'cronJobs' in super then super.cronJobs else [], - }, - isVpaEnabled: if 'isVpaEnabled' in super then super.isVpaEnabled else false, - isLinkConfig: if 'linkConfig' in super && super.linkConfig != null then super.linkConfig else false, - vpa+: { - maxAllowed: { - cpu: if 'cpu' in super then super.cpu else vars.vpa.maxAllowedCPU, - memory: if 'memory' in super then super.memory else vars.vpa.maxAllowedMemory, - }, - }, - allowEgress: if 'allowEgress' in super then super.allowEgress else [], - alerts+: { - pod: mergePodAlerts(vars.deployment.alerts.pod, if 'pod' in super then super.pod else []), - loadBalancer+: [], - database+: [], - kafka+: [], - custom+: [], - kong+: [], - prometheusRecordingRule+: [], - underUtilisedResources+: [], - }, - disableIstio: if 'disableIstio' in super then super.disableIstio else false, - }, - team+: { - name: if 'name' in super then super.name else 'Infra', - }, - [if 'flink' in deployment_manifest_json then null else 'labels']+: { - 'micrometer-prometheus': if 'micrometer-prometheus' in super then super['micrometer-prometheus'] - else if ($.deployment.serviceMonitor.enabled == false && port_map.hasPort($.deployment.exposedPorts, 'metrics')) then 'enabled' else 'disabled', - }, - isSwApmEnabled: if 'isSwApmEnabled' in super then super.isSwApmEnabled else namespace_values.isSwApmEnabled, - extraResources: if 'extraResources' in super then super.extraResources else null, -}; - -local deployment_manifest = deployment_manifest_json + manifest_defaults; - -//For Validation -local rateLimitRulesLength(commonApiGateways) = [ - if 'rateLimitRules' in attribute then std.length(attribute.rateLimitRules) else 0 - for gateway in commonApiGateways - for attribute in gateway.gatewayAttributes -]; -local commonApiGateways = if 'flink' in deployment_manifest then [] else deployment_manifest.deployment.commonApiGateways; -assert std.length([value for value in rateLimitRulesLength(commonApiGateways) if value > 1]) == 0 : 'Apigateway has more than one rateLimiting rule configured in at least one of the gateway attributes'; -assert std.isString(deployment_manifest.cluster) : 'ValidationError: cluster must be a non empty string'; - -deployment_manifest diff --git a/templates/deployment_util.jsonnet b/templates/deployment_util.jsonnet deleted file mode 100644 index d582deb6..00000000 --- a/templates/deployment_util.jsonnet +++ /dev/null @@ -1,108 +0,0 @@ -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local vars = import 'vars.jsonnet'; -local rolloutController = vars.rolloutController; -local deploymentController = deployment.controller; -local ingress = deployment_manifest.deployment.loadBalancers[0]; -local load_balancer_util = import 'load_balancer_util.jsonnet'; -local chart = import 'chart.jsonnet'; -local port_map = import 'port_map.jsonnet'; -local namespace_values = import 'namespace_values.jsonnet'; -local empty(parent, field) = if (field in parent && parent[field] != {} && parent[field] != [] && parent[field] != '') then false else true; - -{ - stepsValueMap(step):: { - manualPromotion: { pause: {} }, - setWeight: { setWeight: step.value }, - pause: { pause: { duration: step.value } }, - }[step.name], - - getSteps(steps):: [ - $.stepsValueMap(step) - for step in steps - ], - - stickinessConfig(stickinessDuration):: { - enabled: true, - durationSeconds: stickinessDuration, - }, - - getMaxSurge(deployment):: - if deployment.maxSurge == null || deployment.maxSurge == '' then - if deployment.hpa.minReplicas <= 5 then '51%' else '20%' - else - deployment.maxSurge + '%', - - strategy:: { - rollingUpdate():: - if (deploymentController == rolloutController) then { - canary: { - maxSurge: $.getMaxSurge(deployment), - maxUnavailable: 0, - }, - } else { - assert deployment.strategy != 'canary' : '%s controller does not support canary' % deploymentController, - type: 'RollingUpdate', - rollingUpdate: { - maxSurge: $.getMaxSurge(deployment), - maxUnavailable: 0, - }, - } - , - - canary(config={}):: { - assert deploymentController == rolloutController : '%s controller is not supported for canary' % deployment.controller, - assert std.find(ingress.type, ['alb', 'sharedAlbAcrossNamespace']) != [] : '%s is not supported for canary' % ingress.type, - local ingressFullName = load_balancer_util.ingress_name(chart.full_service_name(deployment.name), ingress), - local fullName = chart.full_service_name(deployment.name), - local analysisConfig = if !empty(config, 'analysis') then config.analysis else {}, - canary: { - maxSurge: '51%', - maxUnavailable: 0, - [if analysisConfig != {} then 'analysis']: { - templates: [{ - templateName: chart.full_service_name(deployment.name), - }], - [if !empty(analysisConfig, 'templates') && deployment.analysisTemplate != null then 'templates']: analysisConfig.templates, - [if !empty(analysisConfig, 'args') then 'args']: analysisConfig.args, - [if !empty(analysisConfig, 'startingStep') then 'startingStep']: analysisConfig.startingStep, - }, - steps: if empty(config, 'steps') then vars.defaultCanarySteps else $.getSteps(config.steps), - stableService: '%s-stable' % fullName, - canaryService: '%s-canary' % fullName, - trafficRouting: { - alb: { - ingress: ingressFullName, - rootService: fullName, - servicePort: port_map.getPort('serviceport'), - [if 'stickinessDuration' in config && config.stickinessDuration > 0 then 'stickinessConfig']: $.stickinessConfig(config.stickinessDuration), - }, - }, - }, - }, - rollingUpdateWithCanaryMixIn(config={}):: { - assert deploymentController == rolloutController : '%s controller is not supported for canary' % deployment.controller, - assert std.find(ingress.type, ['alb', 'sharedAlbAcrossNamespace']) != [] : '%s is not supported for canary' % ingress.type, - local ingressFullName = load_balancer_util.ingress_name(chart.full_service_name(deployment.name), ingress), - local fullName = chart.full_service_name(deployment.name), - canary: { - maxSurge: '51%', - maxUnavailable: 0, - stableService: '%s-stable' % fullName, - canaryService: '%s-canary' % fullName, - trafficRouting: { - alb: { - ingress: ingressFullName, - rootService: fullName, - servicePort: port_map.getPort('serviceport'), - [if 'stickinessDuration' in config && config.stickinessDuration > 0 then 'stickinessConfig']: $.stickinessConfig(config.stickinessDuration), - }, - }, - [if config.currentStrategy == 'canary' then 'steps']: [{ pause: {} }], - }, - }, - }, - - isEfsNeeded(deployment):: namespace_values.isEfsSupported && 'efs' in deployment, - isFsxNeeded(deployment):: namespace_values.isFsxSupported && 'fsx' in deployment, -} diff --git a/templates/dynamic_configuration.jsonnet b/templates/dynamic_configuration.jsonnet deleted file mode 100644 index 35a995f7..00000000 --- a/templates/dynamic_configuration.jsonnet +++ /dev/null @@ -1,22 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local manifest_util = import 'manifest_util.jsonnet'; -local dynamicConfiguration = if manifest_util.is_dynamic_config_present(deployment_manifest) then deployment_manifest.dynamicConfiguration else {}; - -if manifest_util.is_dynamic_config_present(deployment_manifest) then { - apiVersion: 'v1', - kind: 'Secret', - metadata: { - name: chart.full_service_name(deployment_manifest.deployment.name) + '-dynamic-secret', - namespace: deployment_manifest.deployment.namespace, - labels: common.labels, - annotations: common.annotations, - }, - stringData: - { - [config.fileName]: config.data - for config in dynamicConfiguration - }, - type: 'Opaque', -} diff --git a/templates/efs_persistent_volume_claim.jsonnet b/templates/efs_persistent_volume_claim.jsonnet deleted file mode 100644 index 94137d23..00000000 --- a/templates/efs_persistent_volume_claim.jsonnet +++ /dev/null @@ -1,34 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment_util = import 'deployment_util.jsonnet'; -local deployment = deployment_manifest.deployment; -local namespace_values = import 'namespace_values.jsonnet'; - -if (deployment_util.isEfsNeeded(deployment)) then - local efs_list = deployment.efs; - if (std.length(efs_list) != 0) then - { - apiVersion: 'v1', - kind: 'List', - items: std.map(function(efs) { - apiVersion: 'v1', - kind: 'PersistentVolumeClaim', - metadata: { - name: chart.full_service_name(deployment.name) + '-' + efs.name, - labels: common.labels, - annotations: common.annotations, - namespace: deployment.namespace, - }, - spec: { - accessModes: ['ReadWriteMany'], - storageClassName: efs.name, - resources: { - requests: { - storage: '1Mi', - }, - }, - }, - }, efs_list), - } - else null diff --git a/templates/elastic_search.jsonnet b/templates/elastic_search.jsonnet deleted file mode 100644 index 13081fb3..00000000 --- a/templates/elastic_search.jsonnet +++ /dev/null @@ -1,90 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local PVCAnnotations = '{ "Team": "%s", "Environment": "%s", "Product": "%s" }' % [deployment_manifest.team.name, deployment_manifest.environment, deployment_manifest.metadata.product]; -if deployment_manifest.deployment.elasticSearch.enabled == true then { - apiVersion: 'elasticsearch.k8s.elastic.co/v1', - kind: 'Elasticsearch', - metadata: { - name: deployment.elasticSearch.instance.instanceName + '-elasticsearch', - namespace: deployment_manifest.environment + '-datastores', - labels: deployment.elasticSearch.esLabels, - annotations: common.annotations, - }, - spec: { - version: deployment.elasticSearch.esVersion, - image: deployment.elasticSearch.esImage, - secureSettings: [ - { - secretName: 'aws-credentials-es-backup', - }, - ], - http: { - tls: { - selfSignedCertificate: { - disabled: true, - }, - }, - }, - nodeSets: [ - { - name: 'node', - config: { - 'node.roles': [ - 'master', - 'data', - 'ingest', - ], - 'node.store.allow_mmap': false, - }, - podTemplate: { - metadata: { - labels: deployment.elasticSearch.esLabels, - }, - spec: { - nodeSelector: deployment.elasticSearch.esNodeSelector, - tolerations: deployment.elasticSearch.esTolerations, - containers: [ - { - name: 'elasticsearch', - resources: { - requests: { - memory: deployment.elasticSearch.instance.memory, - cpu: deployment.elasticSearch.instance.cpu, - }, - limits: { - memory: deployment.elasticSearch.instance.memory, - cpu: deployment.elasticSearch.instance.cpu, - }, - }, - }, - ], - }, - }, - count: deployment.elasticSearch.esCount, - volumeClaimTemplates: [ - { - metadata: { - name: 'elasticsearch-data', - annotations: { - 'k8s-pvc-tagger/tags': PVCAnnotations - } - }, - spec: { - accessModes: [ - 'ReadWriteOnce', - ], - resources: { - requests: { - storage: deployment.elasticSearch.instance.diskSpace, - }, - }, - storageClassName: 'gp3-retain-policy', - }, - }, - ], - }, - ], - }, -} diff --git a/templates/elasticsearch_alerts_default.jsonnet b/templates/elasticsearch_alerts_default.jsonnet deleted file mode 100644 index 687dffa2..00000000 --- a/templates/elasticsearch_alerts_default.jsonnet +++ /dev/null @@ -1,186 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local namespace_values = import 'namespace_values.jsonnet'; -local app_name = chart.full_service_name(deployment_manifest.deployment.name); -local namespace = deployment_manifest.deployment.namespace; -local deployment = deployment_manifest.deployment; - -local clusterName = deployment.elasticSearch.instance.instanceName + '-elasticsearch'; - -if deployment_manifest.deployment.elasticSearch.enabled == true then { - apiVersion: 'monitoring.coreos.com/v1', - kind: 'PrometheusRule', - metadata: { - labels: deployment.elasticSearch.esLabels { - prometheus: 'kube-prometheus', - role: 'alert-rules', - }, - annotations: common.annotations, - name: clusterName + '-alerts', - namespace: deployment_manifest.environment + '-datastores', - }, - spec: { - groups: [ - { - name: clusterName + '-alerts', - rules: [ - { - alert: 'ElasticsearchHeapUsageTooHigh', - expr: '(es_jvm_mem_heap_used_bytes{job=~".*http",es_cluster="%(clustername)s"} / es_jvm_mem_heap_max_bytes{job=~".*http",es_cluster="%(clustername)s"}) * 100 > 90' % ({ clustername: clusterName }), - 'for': '20m', - labels: { - severity: 'critical', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch Heap Usage Too High (node `{{ $labels.node }}`)', - description: 'The heap usage is over 90% for 5m VALUE = `{{ $value }}`\n NAME: `{{ $labels.node }}`', - }, - }, - { - alert: 'ElasticsearchHeapUsageWarning', - expr: '(es_jvm_mem_heap_used_bytes{job=~".*http",es_cluster="%(clustername)s"} / es_jvm_mem_heap_max_bytes{job=~".*http",es_cluster="%(clustername)s"}) * 100 > 80' % ({ clustername: clusterName }), - 'for': '15m', - labels: { - severity: 'warning', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch Heap Usage warning (node `{{ $labels.node }}`)', - description: 'The heap usage is over 80% for 15m\n VALUE = `{{ $value }}`\n NAME: `{{ $labels.node }}`', - }, - }, - { - alert: 'ElasticsearchAvgDiskOutOfSpace_Warning', - expr: '(es_fs_total_free_bytes{job=~".*http",es_cluster="%(clustername)s"}/es_fs_total_total_bytes{job=~".*http",es_cluster="%(clustername)s"}) * 100 < 15' % ({ clustername: clusterName }), - 'for': '20m', - labels: { - severity: 'warning', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch average disk out of space (node - `{{ $labels.node }}`). No new shards will be allocated at this node', - description: 'The disk usage is over 85%\n VALUE = `{{ $value }}`', - }, - }, - { - alert: 'ElasticsearchDiskOutOfSpace', - expr: '(es_fs_total_free_bytes{job=~".*http",es_cluster="%(clustername)s"}/es_fs_total_total_bytes{job=~".*http",es_cluster="%(clustername)s"}) * 100 < 10' % ({ clustername: clusterName }), - 'for': '10m', - labels: { - severity: 'critical', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch disk out of space (node `{{ $labels.node }}`). No new shards will be allocated at this node', - description: 'The disk usage is over 90%\n VALUE = `{{ $value }}`\n NAME: `{{ $labels.node }}`', - }, - }, - { - alert: 'ElasticsearchClusterRed', - expr: 'max(es_cluster_status{job=~".*http",es_cluster="%(clustername)s"}) by (es_cluster) == 2' % ({ clustername: clusterName }), - 'for': '5m', - labels: { - severity: 'critical', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch Cluster Red (cluster - `{{ $labels.es_cluster }}`)', - description: 'Elastic Cluster Red', - }, - }, - { - alert: 'ElasticsearchClusterYellow', - expr: 'max(es_cluster_status{job=~".*http",es_cluster="%(clustername)s"}) by (es_cluster) == 1' % ({ clustername: clusterName }), - 'for': '15m', - labels: { - severity: 'warning', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch Cluster Yellow (cluster - `{{ $labels.es_cluster }}`)', - description: 'Elastic Cluster Yellow for 15 minutes', - }, - }, - { - alert: 'ElasticsearchClusterIndexReplicaUnavailable', - expr: 'min(es_index_replicas_number{job=~".*http",es_cluster="%(clustername)s",index!~"^[.].*"}) by (es_cluster,index) < 1' % ({ clustername: clusterName }), - 'for': '15m', - labels: { - severity: 'warning', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch Cluster Index Replica less than 1 (cluster - `{{ $labels.es_cluster }}`)', - description: 'Elastic Cluster Index Replica less than 1 for 15 minutes\n VALUE = `{{ $value }}`', - }, - }, - { - alert: 'ElasticsearchInitializingShards', - expr: 'max(es_cluster_shards_number{type="initializing",job=~".*http",es_cluster="%(clustername)s"}) by (es_cluster) > 0' % ({ clustername: clusterName }), - 'for': '10m', - labels: { - severity: 'warning', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch initializing shards (cluster `{{ $labels.es_cluster }}`)', - description: 'Number of initializing shards for 10 min\n VALUE = `{{ $value }}`', - }, - }, - { - alert: 'ElasticsearchUnassignedShards', - expr: 'max(es_cluster_shards_number{type="unassigned",job=~".*http",es_cluster="%(clustername)s"}) by (es_cluster) > 0' % ({ clustername: clusterName }), - 'for': '30m', - labels: { - severity: 'critical', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch unassigned shards (cluster `{{ $labels.es_cluster }}`)', - description: 'Number of unassigned shards for 30 min\n VALUE = `{{ $value }}`', - }, - }, - { - alert: 'ElasticsearchUnassignedShards', - expr: 'max(es_cluster_shards_number{type="unassigned",job=~".*http",es_cluster="%(clustername)s"}) by (es_cluster) > 0' % ({ clustername: clusterName }), - 'for': '15m', - labels: { - severity: 'warning', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch unassigned shards (cluster `{{ $labels.es_cluster }}`)', - description: 'Number of unassigned shards for 15 min\n VALUE = `{{ $value }}`', - }, - }, - { - alert: 'ElasticsearchPendingTasks', - expr: 'max(es_cluster_pending_tasks_number{job=~".*http",es_cluster="%(clustername)s"}) by (es_cluster) > 0' % ({ clustername: clusterName }), - 'for': '15m', - labels: { - severity: 'warning', - alertTeam: deployment_manifest.team.name, - appName: clusterName, - }, - annotations: { - summary: 'Elasticsearch pending tasks (cluster `{{ $labels.es_cluster }}`)', - description: 'Number of pending tasks for 15 min. Cluster works slowly.\n VALUE = `{{ $value }}`', - }, - }, - ], - }, - ], - }, -} diff --git a/templates/elasticsearch_secrets.jsonnet b/templates/elasticsearch_secrets.jsonnet deleted file mode 100644 index 17e1b275..00000000 --- a/templates/elasticsearch_secrets.jsonnet +++ /dev/null @@ -1,18 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; - -if deployment_manifest.deployment.elasticSearch.enabled == true then { - apiVersion: 'v1', - kind: 'Secret', - metadata: { - name: deployment.elasticSearch.instance.instanceName + '-elasticsearch' + '-es-elastic-user', - namespace: deployment_manifest.environment + '-datastores', - labels: deployment.elasticSearch.esLabels, - annotations: common.annotations, - }, - - data: { [e.name]: std.base64(e.value) for e in deployment_manifest.environmentVariables if std.toString(e.name) == 'elastic' }, - type: 'Opaque', -} diff --git a/templates/elasticsearch_servicemonitor.jsonnet b/templates/elasticsearch_servicemonitor.jsonnet deleted file mode 100644 index 646af3e9..00000000 --- a/templates/elasticsearch_servicemonitor.jsonnet +++ /dev/null @@ -1,75 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; - -if deployment_manifest.deployment.elasticSearch.enabled == true then { - apiVersion: 'monitoring.coreos.com/v1', - kind: 'ServiceMonitor', - metadata: { - labels: deployment.elasticSearch.esLabels, - name: deployment.elasticSearch.instance.instanceName + '-elasticsearch-monitor', - namespace: deployment_manifest.environment + '-datastores', - annotations: common.annotations, - }, - spec: { - endpoints: [ - { - metricRelabelings: [ - { - action: 'drop', - regex: 'es_index_segments_memory_bytes', - sourceLabels: ['__name__'], - }, - { - action: 'drop', - regex: '.*es-node', - sourceLabels: ['job'], - }, - { - action: 'drop', - regex: 'es_cluster.*;.*es-node-[1-9]+', - sourceLabels: ['__name__', 'pod'], - }, - { - sourceLabels: ['cluster'], - targetLabel: 'es_cluster', - replacement: '$1' - }, - { - action: 'labeldrop', - regex: '^cluster$', - } - ], - interval: '30s', - path: '/_prometheus/metrics', - port: 'http', - scheme: 'http', - tlsConfig: { - insecureSkipVerify: true, - }, - basicAuth: { - password: { - name: deployment.elasticSearch.instance.instanceName + '-elasticsearch' + '-sm-secret', - key: 'password', - }, - username: { - name: deployment.elasticSearch.instance.instanceName + '-elasticsearch' + '-sm-secret', - key: 'username', - }, - }, - }, - ], - namespaceSelector: { - matchNames: [ - deployment_manifest.environment + '-datastores', - ], - }, - selector: { - matchLabels: { - 'common.k8s.elastic.co/type': 'elasticsearch', - 'elasticsearch.k8s.elastic.co/cluster-name': deployment.elasticSearch.instance.instanceName + '-elasticsearch', - }, - }, - }, -} diff --git a/templates/elasticsearch_sm_secrets.jsonnet b/templates/elasticsearch_sm_secrets.jsonnet deleted file mode 100644 index 2295b1b1..00000000 --- a/templates/elasticsearch_sm_secrets.jsonnet +++ /dev/null @@ -1,18 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; - -if deployment_manifest.deployment.elasticSearch.enabled == true then { - apiVersion: 'v1', - kind: 'Secret', - metadata: { - name: deployment.elasticSearch.instance.instanceName + '-elasticsearch' + '-sm-secret', - namespace: deployment_manifest.environment + '-datastores', - labels: deployment.elasticSearch.esLabels, - annotations: common.annotations, - }, - - data: { ['username']: std.base64(e.name) for e in deployment_manifest.environmentVariables if std.toString(e.name) == 'elastic' } + { ['password']: std.base64(e.value) for e in deployment_manifest.environmentVariables if std.toString(e.name) == 'elastic' }, - type: 'Opaque', -} diff --git a/templates/elasticsearch_snapshots.jsonnet b/templates/elasticsearch_snapshots.jsonnet deleted file mode 100644 index 2962a335..00000000 --- a/templates/elasticsearch_snapshots.jsonnet +++ /dev/null @@ -1,122 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; - -if deployment_manifest.deployment.elasticSearch.enabled == true then { - apiVersion: 'batch/v1', - kind: 'Job', - metadata: { - name: deployment.elasticSearch.instance.instanceName + '-elasticsearch' + '-init-snapshots', - namespace: deployment_manifest.environment + '-datastores', - labels: deployment.elasticSearch.esLabels, - annotations: common.annotations, - }, - spec: { - template: { - spec: { - initContainers: [ - { - name: 'elasticsearch-s3-repository', - image: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/centos:7-custom', - imagePullPolicy: 'IfNotPresent', - volumeMounts: [ - { - name: 'es-basic-auth', - mountPath: '/mnt/elastic/es-basic-auth', - }, - ], - env: [ - { - name: 'ES_HOST', - value: deployment.elasticSearch.instance.instanceName + '-elasticsearch-es-http.' + deployment_manifest.environment + '-datastores.' + 'svc.cluster.local', - }, - { - name: 'ES_PORT', - value: '9200', - }, - { - name: 'ES_REPOSITORY', - value: 'snapshots', - }, - { - name: 'S3_REGION', - value: 'ap-south-1', - }, - { - name: 'S3_BUCKET', - valueFrom: { - secretKeyRef: { - name: 's3-bucket-es-backup', - key: 'bucket', - }, - }, - }, - { - name: 'S3_BASE_PATH', - value: deployment.elasticSearch.instance.instanceName, - }, - { - name: 'S3_COMPRESS', - value: 'true', - }, - { - name: 'S3_STORAGE_CLASS', - value: 'standard', - }, - ], - command: [ - '/bin/sh', - '-c', - ], - args: [ - "dockerize -wait tcp://${ES_HOST}:${ES_PORT} -timeout 600s && curl -s -i -k -u \"elastic:$(\"'\",\n \"repository\": \"'\"${ES_REPOSITORY}\"'\",\n \"config\": {\n \"indices\": \"'\"*\"'\",\n \"include_global_state\": \"'\"true\"'\"\n },\n \"retention\": {\n \"expire_after\": \"7d\",\n \"min_count\": 7,\n \"max_count\": 14\n }\n}'\n", - ], - }, - ], - restartPolicy: 'Never', - volumes: [ - { - name: 'es-basic-auth', - secret: { - secretName: deployment.elasticSearch.instance.instanceName + '-elasticsearch' + '-es-elastic-user', - }, - }, - ], - }, - }, - }, -} diff --git a/templates/flink_default_alerts.jsonnet b/templates/flink_default_alerts.jsonnet deleted file mode 100644 index 7b510440..00000000 --- a/templates/flink_default_alerts.jsonnet +++ /dev/null @@ -1,238 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local namespace_values = import 'namespace_values.jsonnet'; -local app_name = chart.full_service_name(deployment_manifest.name); -local namespace = deployment_manifest.flink.namespace; -local load_balancer_util = import 'load_balancer_util.jsonnet'; -local manifest_util = import 'manifest_util.jsonnet'; -local flink = deployment_manifest.flink; -local vars = import 'vars.jsonnet'; -local util = import 'util.jsonnet'; - -local environment = deployment_manifest.environment; -local commonAlertFields = { - appName: common.awsTags.Name, - fullName: chart.full_service_name(deployment_manifest.name), - namespace: namespace, - environment: environment, -}; -local baseLabels = function(alert) { - labels: { - severity: alert.severity, - alertTeam: deployment_manifest.team.name, - appName: app_name, - [if manifest_util.is_custom_slack_channel_enabled(alert) then 'slackChannel']: alert.slackChannel, - }, -}; -local baseAnnotations = function(alert) { - annotations: { - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/509936863/Runbook', - }, -}; -local mapAlerts(alertGroup, alerts) = std.filterMap( - function(alert) alert.type in alertGroup, - function(alert) baseAnnotations(alert) + alertGroup[alert.type](alert) + baseLabels(alert), - alerts -); - -local alerts = { - "pod": [ - { - "type": "HighPodRestarts", - "duration": "30m", - "severity": "critical", - "threshold": 3 - }, - { - "type": "HighPodFailures", - "duration": "3h", - "severity": "warning", - "threshold": 2 - }, - { - "type": "FrequentPodOOMKilled", - "duration": "10m", - "severity": "critical", - "threshold": 2 - }, - { - "type": "PodOOMKilled", - "duration": "5m", - "severity": "warning", - "threshold": 1 - }, - { - "type": "KubeContainerWaiting", - "duration": "1h", - "severity": "critical", - "threshold": 0 - } - ], - "flink": [ - { - "type": "JobManagerJvmMemoryUsageHigh", - "duration": "10m", - "severity": "critical", - "threshold": 85 - }, - { - "type": "JobManagerCpuLoadHigh", - "duration": "10m", - "severity": "critical", - "threshold": 75 - }, - { - "type": "TaskManagerJvmCpuLoadHigh", - "duration": "10m", - "severity": "critical", - "threshold": 75 - }, - { - "type": "TaskManagerJvmMemoryUsageHigh", - "duration": "10m", - "severity": "critical", - "threshold": 85 - }, - { - "type": "JobManagerFailedCheckpointIncreased", - "duration": "5m", - "severity": "critical", - "threshold": 0 - }, - { - "type": "FlinkTaskFailed", - "duration": "5m", - "severity": "critical", - "threshold": 0 - } - ], - "custom": [] -}; - -local podAlerts = { - HighPodRestarts: function(alert) ({ - alert: 'HighPodRestarts', - annotations: { - description: 'Namespace: %s, AppName: %s; Pod restarted multiple times' % [namespace, app_name], - summary: 'High Pod Restarts', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: 'sum(increase(kube_pod_container_status_restarts_total{namespace="%s", pod=~"%s.*"}[%s])) > %s' % [namespace, app_name, alert.duration, alert.threshold], - }), - HighPodFailures: function(alert) ({ - alert: 'HighPodFailures', - annotations: { - description: 'Namespace: %s, AppName: %s; Pods were last terminated due to reason {{ $labels.reason }}' % [namespace, app_name], - summary: 'High Pod Failures', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: 'sum(increase(kube_pod_container_status_last_terminated_reason{namespace="%s", container=~"%s.*",reason !~ "Completed|Evicted|OOMKilled"}[%s])) by (reason,pod) > %s' % [namespace, app_name, alert.duration, alert.threshold], - }), - FrequentPodOOMKilled: function(alert) ({ - alert: 'FrequentPodOOMKilled', - annotations: { - description: 'Namespace: %s, AppName: %s; Pod: {{ $labels.pod }} is restarting multiple times because of OOMKilled' % [namespace, app_name], - summary: 'High Pod Failures', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: 'increase(kube_pod_container_status_restarts_total{namespace="%s", container="%s"}[%s]) >= %s AND ignoring(reason) kube_pod_container_status_last_terminated_reason{namespace="%s", container="%s", reason="OOMKilled"} > 0' % [namespace, app_name, alert.duration, alert.threshold, namespace, app_name], - }), - PodOOMKilled: function(alert) ({ - alert: 'PodOOMKilled', - annotations: { - description: 'Namespace: %s, AppName: %s; Pod: {{ $labels.pod }} killed because of OOMKilled' % [namespace, app_name], - summary: 'Pod OOMKilled', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: 'kube_pod_container_status_restarts_total{namespace="%s", container="%s"} - kube_pod_container_status_restarts_total{namespace="%s", container="%s"} offset %s >= %s AND ignoring(reason) kube_pod_container_status_last_terminated_reason{namespace="%s", container="%s", reason="OOMKilled"} > 0' % [namespace, app_name, namespace, app_name, alert.duration, alert.threshold, namespace, app_name], - }), - KubeContainerWaiting: function(alert) ({ - alert: 'KubeContainerWaiting', - annotations: { - description: 'Namespace: %s, AppName: %s; container in waiting state for one hour' % [namespace, app_name], - summary: 'container is waiting for too long', - runbook: 'https://navihq.atlassian.net/wiki/spaces/IN/pages/279937094/Act+On+Pod+Alert', - }, - expr: 'sum by (namespace, pod, container) (kube_pod_container_status_waiting_reason{container="%s", namespace="%s"}) > %s' % [app_name, namespace, alert.threshold], - 'for': alert.duration, - }), -}; - -local flinkAlerts = { - JobManagerJvmMemoryUsageHigh: function(alert) ({ - alert: 'JobManagerJvmMemoryUsageHigh', - annotations: { - description: 'Namespace: %s, AppName: %s; JVM Memory usage more than 80 percent for flink job {{ $labels.job }} since last %s ' % [namespace, app_name, alert.duration], - summary: 'Job Manager JVM Memory Usage High', - }, - expr: '( flink_jobmanager_Status_JVM_Memory_Heap_Used / flink_jobmanager_Status_JVM_Memory_Heap_Max ) * 100 > %s ' % [alert.threshold], - 'for': alert.duration, - }), - JobManagerCpuLoadHigh: function(alert) ({ - alert: 'JobManagerCpuLoadHigh', - annotations: { - description: 'Namespace: %s, AppName: %s; JVM CPU Load more than %s for flink job {{ $labels.job }} since last %s.' % [namespace, app_name,alert.threshold, alert.duration], - summary: 'Job Manager CPU Load High', - }, - expr: 'flink_jobmanager_Status_JVM_CPU_Load > %s' % alert.threshold, - 'for': alert.duration, - }), - TaskManagerJvmCpuLoadHigh: function(alert) ({ - alert: 'TaskManagerJvmCpuLoadHigh', - annotations: { - description: 'Namespace: %s, AppName: %s; JVM CPU Load more than %s for flink taskmanager {{ $labels.tm_id }} for job {{ $labels.job }} since last %s.' % [namespace, app_name, alert.threshold, alert.duration], - summary: 'Task Manager JVM CPU Load High', - }, - expr: 'flink_taskmanager_Status_JVM_CPU_Load > %s' % alert.threshold, - 'for': alert.duration, - }), - TaskManagerJvmMemoryUsageHigh: function(alert) ({ - alert: 'TaskManagerJvmMemoryUsageHigh', - annotations: { - description: 'Namespace: %s, AppName: %s; JVM Memory usage more than 80 percent for TaskManager {{ $labels.tm_id }} for job {{ $labels.job }} since last %s.' % [namespace, app_name, alert.duration], - summary: 'Task Manager JVM Memory Usage High', - }, - expr: '(flink_taskmanager_Status_JVM_Memory_Heap_Used / flink_taskmanager_Status_JVM_Memory_Heap_Max) * 100 > %s' % alert.threshold, - 'for': alert.duration, - }), - JobManagerFailedCheckpointIncreased: function(alert) ({ - alert: 'JobManagerFailedCheckpointIncreased', - annotations: { - description: 'Namespace: %s, AppName: %s; Number of failed checkpoints increased in last %s for job {{ $labels.job }}' % [namespace, app_name, alert.duration], - summary: 'Job Manager Failed Checkpoint Increased', - }, - expr: 'increase(flink_jobmanager_job_numberOfFailedCheckpoints[%s]) > 0' % alert.duration, - }), - FlinkTaskFailed: function(alert) ({ - alert: 'FlinkTaskFailed', - annotations: { - description: 'Namespace: %s, AppName: %s; The Flink job {{ $labels.job }} has tasks that failed.' % [namespace, app_name], - summary: 'Flink Task Failed', - }, - expr: 'rate(flink_taskmanager_job_task_failed{job="{{ $labels.job }}"}[%s]) > 0' % alert.duration, - 'for': alert.duration, - }), -}; - -{ - apiVersion: 'monitoring.coreos.com/v1', - kind: 'PrometheusRule', - metadata: { - labels: common.labels { - prometheus: 'kube-prometheus', - role: 'alert-rules', - }, - name: app_name, - namespace: namespace, - annotations: common.annotations, - }, - spec: { - groups: [ - { - name: '%s-basic' % [app_name], - rules: (mapAlerts(podAlerts, alerts.pod) + mapAlerts(flinkAlerts, alerts.flink)), - }, - ], - }, -} diff --git a/templates/flink_deployment.jsonnet b/templates/flink_deployment.jsonnet deleted file mode 100644 index 0f6906f0..00000000 --- a/templates/flink_deployment.jsonnet +++ /dev/null @@ -1,172 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local flink = deployment_manifest.flink; -local namespace_values = import 'namespace_values.jsonnet'; -local flinkBucket = namespace_values.flinkBucket; -local flinkBucketBaseDir = 's3://' + flinkBucket + '/jobs/' + deployment_manifest.environment + '/' + deployment_manifest.name; -local util = import 'util.jsonnet'; -local needsAWSAccess = if util.is_field_present(deployment_manifest.extraResources, 'aws_access') - && util.is_field_present(deployment_manifest.extraResources.aws_access, 'policies') - && std.length(deployment_manifest.extraResources.aws_access.policies) > 0 then true else false; - -local roleName = chart.full_service_name(deployment_manifest.name) + '-' + deployment_manifest.environment; - -local awsAccess = { - volumeName:: 'aws-iam-credentials', - volumeMountPath:: '/meta/aws-iam', - - volume: if (needsAWSAccess && namespace_values.zalandoEnabled) then [ - { name: $.volumeName, secret: { secretName: roleName, defaultMode: 420 } }, - ] else [], - mount: if (needsAWSAccess && namespace_values.zalandoEnabled) then [ - { name: $.volumeName, mountPath: $.volumeMountPath }, - ] else [], - env: if (needsAWSAccess && namespace_values.zalandoEnabled) then [ - { name: 'AWS_DEFAULT_REGION', value: 'ap-south-1' }, - { name: 'AWS_SHARED_CREDENTIALS_FILE', value: $.volumeMountPath + '/credentials.process' }, - { name: 'AWS_CREDENTIAL_PROFILES_FILE', value: $.volumeMountPath + '/credentials' }, - ] else [], -}; - -local rocksDbSupport = { - name:: 'rocksdb-storage', - storageClassName:: 'gp2', - mountPath:: '/opt/flink/rocksdb', - accessModes:: ['ReadWriteOnce'], - - volume: { - name: $.name, - ephemeral: { - volumeClaimTemplate: { - metadata: { - labels: common.labels, - }, - spec: { - accessModes: $.accessModes, - storageClassName: $.storageClassName, - resources: { - requests: { - storage: flink.flinkDeployment.taskManager.volumeSize, - }, - }, - }, - }, - }, - }, - mount: { - name: $.name, - mountPath: $.mountPath, - }, -}; - -{ - mainContainerName:: 'flink-main-container', - image:: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/flink:1.17.2-s3-hadoop', - flinkVersion:: 'v1_17', - defaultStateBackendType:: 'filesystem', - isRocksDbSupportEnabled:: ('volumeSize' in flink.flinkDeployment.taskManager), - isCustomTaskManagerPodTemplateRequired:: ($.isRocksDbSupportEnabled), - stateBackendType:: ( - if $.isRocksDbSupportEnabled then - 'rocksdb' - else - $.defaultStateBackendType - ), - - apiVersion: 'flink.apache.org/v1beta1', - kind: 'FlinkDeployment', - metadata: { - name: deployment_manifest.name, - namespace: flink.namespace, - }, - spec: { - image: $.image, - imagePullPolicy: 'IfNotPresent', - flinkVersion: $.flinkVersion, - restartNonce: flink.flinkDeployment.restartNonce, - flinkConfiguration: { - 'taskmanager.numberOfTaskSlots': std.toString(flink.flinkDeployment.flinkConfiguration.taskManagerSlots), - 'high-availability': 'KUBERNETES', - 'high-availability.storageDir': flinkBucketBaseDir + '/recovery', - 'state.backend.type': $.stateBackendType, - [if $.isRocksDbSupportEnabled then 'state.backend.rocksdb.localdir']: rocksDbSupport.mountPath, - 'state.checkpoints.dir': flinkBucketBaseDir + '/checkpoints', - 'state.savepoints.dir': flinkBucketBaseDir + '/savepoints', - 'kubernetes.operator.periodic.savepoint.interval': flink.flinkDeployment.flinkConfiguration.savepointFrequency, - 'kubernetes.operator.savepoint.history.max.count': '24', - 'kubernetes.operator.pod-template.merge-arrays-by-name': 'true', - 'restart-strategy': 'exponentialdelay', - 'execution.checkpointing.interval': '30s', - 'restart-strategy.exponential-delay.initial-backoff': '10s', - 'restart-strategy.exponential-delay.max-backoff': '2min', - 'restart-strategy.exponential-delay.backoff-multiplier': '2.0', - 'restart-strategy.exponential-delay.reset-backoff-threshold': '10min', - 'restart-strategy.exponential-delay.jitter-factor': '0.1', - 'metrics.reporter.promgateway.jobName': deployment_manifest.name, - 'metrics.reporter.promgateway.groupingKey': 'tag_team=' + deployment_manifest.team.name, - }, - serviceAccount: roleName, - podTemplate: { - apiVersion: 'v1', - kind: 'Pod', - metadata: { - name: deployment_manifest.name, - labels: common.labels, - }, - spec: { - containers: [ - { - name: $.mainContainerName, - env: [ - { - name: e.name, - valueFrom: { - secretKeyRef: { - name: chart.full_service_name(deployment_manifest.name) + '-secret', - key: e.name, - }, - }, - } - for e in deployment_manifest.environmentVariables - ] + - // Adding md5 to make sure deployment is retrigerred if just values are changed - ([{ name: 'secretMd5', value: std.md5(std.toString(deployment_manifest.environmentVariables)) }]) + - awsAccess.env, - volumeMounts: awsAccess.mount, - }, - ], - volumes: awsAccess.volume, - serviceAccountName: roleName, - }, - }, - jobManager: { - replicas: flink.flinkDeployment.jobManager.replicas, - resource: { - memory: flink.flinkDeployment.jobManager.resources.memory, - cpu: flink.flinkDeployment.jobManager.resources.cpu, - }, - }, - taskManager: { - [if $.isCustomTaskManagerPodTemplateRequired then 'podTemplate']: { - spec: { - securityContext: { - fsGroup: 9999, - }, - containers: [ - { - name: $.mainContainerName, - volumeMounts: [rocksDbSupport.mount], - }, - ], - volumes: [rocksDbSupport.volume], - }, - }, - replicas: flink.flinkDeployment.taskManager.replicas, - resource: { - memory: flink.flinkDeployment.taskManager.resources.memory, - cpu: flink.flinkDeployment.taskManager.resources.cpu, - }, - }, - }, -} diff --git a/templates/flink_role_binding.jsonnet b/templates/flink_role_binding.jsonnet deleted file mode 100644 index 7685f52b..00000000 --- a/templates/flink_role_binding.jsonnet +++ /dev/null @@ -1,27 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local namespace = deployment_manifest.flink.namespace; - -local serviceAccountName = chart.full_service_name(deployment_manifest.name) + '-' + deployment_manifest.environment; -{ - apiVersion: 'rbac.authorization.k8s.io/v1', - kind: 'RoleBinding', - metadata: { - name: 'flink' + '-' + serviceAccountName, - namespace: namespace, - labels: common.labels, - }, - roleRef: { - apiGroup: 'rbac.authorization.k8s.io', - kind: 'Role', - name: 'flink', - }, - subjects: [ - { - kind: 'ServiceAccount', - name: serviceAccountName, - namespace: namespace, - }, - ], -} diff --git a/templates/flink_service_account.jsonnet b/templates/flink_service_account.jsonnet deleted file mode 100644 index 5225463f..00000000 --- a/templates/flink_service_account.jsonnet +++ /dev/null @@ -1,27 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local namespace = deployment_manifest.flink.namespace; -local namespace_values = import 'namespace_values.jsonnet'; -local util = import 'util.jsonnet'; -local needsAWSAccess = if util.is_field_present(deployment_manifest.extraResources, 'aws_access') - && util.is_field_present(deployment_manifest.extraResources.aws_access, 'policies') - && std.length(deployment_manifest.extraResources.aws_access.policies) > 0 then true else false; - -local roleName = chart.full_service_name(deployment_manifest.name) + '-' + deployment_manifest.environment; - - -{ - apiVersion: 'v1', - kind: 'ServiceAccount', - metadata: ({ - name: roleName, - namespace: namespace, - labels: common.labels, - [if !namespace_values.zalandoEnabled then 'annotations' else null]: { - 'eks.amazonaws.com/role-arn': 'arn:aws:iam::' + namespace_values.awsAccountId + ':role/' + roleName, - 'eks.amazonaws.com/sts-regional-endpoints': 'true', - 'eks.amazonaws.com/token-expiration': '10800', - }, - }), -} diff --git a/templates/flink_session_job.jsonnet b/templates/flink_session_job.jsonnet deleted file mode 100644 index c99993f9..00000000 --- a/templates/flink_session_job.jsonnet +++ /dev/null @@ -1,24 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local flink = deployment_manifest.flink; -local namespace_values = import 'namespace_values.jsonnet'; -{ - apiVersion: 'flink.apache.org/v1beta1', - kind: 'FlinkSessionJob', - metadata: { - name: deployment_manifest.name, - namespace: flink.namespace, - }, - spec: { - deploymentName: deployment_manifest.name, - job: { - jarURI: std.extVar('IMAGE'), - parallelism: flink.flinkJob.parallelism, - allowNonRestoredState: true, - upgradeMode: 'savepoint', - [if 'entryClass' in flink.flinkJob then 'entryClass' else null]: flink.flinkJob.entryClass, - args: [flink.flinkJob.jobArguments], - }, - }, -} diff --git a/templates/health_check_values.jsonnet b/templates/health_check_values.jsonnet deleted file mode 100644 index f0b7da71..00000000 --- a/templates/health_check_values.jsonnet +++ /dev/null @@ -1,65 +0,0 @@ -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local port_map = import 'port_map.jsonnet'; -local exposedPorts = deployment_manifest.deployment.exposedPorts; - - -local isMicrometerPrometheusEnabled = deployment_manifest.labels['micrometer-prometheus'] == 'enabled'; -local error_message = 'Metrics port not specified with micrometer-prometheus enabled'; - -local defaultReadinessCheck = { - type: 'tcp', - port: 'serviceport', - path: '/actuator/health', - successThreshold: 1, - initialDelaySeconds: 60, - periodSeconds: 30, - failureThreshold: 5, - httpHeaders: [], -}; - -local defaultLivenessCheck = { - type: 'tcp', - port: 'serviceport', - path: '/actuator/health', - successThreshold: 1, - initialDelaySeconds: 60, - periodSeconds: 30, - failureThreshold: 5, - httpHeaders: [], -} + if isMicrometerPrometheusEnabled then { port: 'metrics', type: 'http' } else {}; - -local defaultStartupProbe = { - successThreshold: 1, - initialDelaySeconds: 0, - periodSeconds: 10, - failureThreshold: 30, - httpHeaders: [], -}; - -{ - generator(healthCheck): { - http:: { - httpGet: { - port: port_map.getPort(healthCheck.port), - path: healthCheck.path, - httpHeaders: healthCheck.httpHeaders, - }, - successThreshold: healthCheck.successThreshold, - initialDelaySeconds: healthCheck.initialDelaySeconds, - periodSeconds: healthCheck.periodSeconds, - failureThreshold: healthCheck.failureThreshold, - }, - tcp:: { - tcpSocket: { - port: port_map.getPort(healthCheck.port), - }, - successThreshold: healthCheck.successThreshold, - initialDelaySeconds: healthCheck.initialDelaySeconds, - periodSeconds: healthCheck.periodSeconds, - failureThreshold: healthCheck.failureThreshold, - }, - }, - getDefaultReadinessCheck:: defaultReadinessCheck, - getDefaultStartupProbe:: defaultStartupProbe, - getDefaultLivenessCheck:: if (isMicrometerPrometheusEnabled && !port_map.hasPort(exposedPorts, 'metrics')) then error error_message else defaultLivenessCheck, -} diff --git a/templates/hpa.jsonnet b/templates/hpa.jsonnet deleted file mode 100644 index 945db992..00000000 --- a/templates/hpa.jsonnet +++ /dev/null @@ -1,70 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local hpa = deployment.hpa; -local vars = import 'vars.jsonnet'; -local util = import 'util.jsonnet'; - -local hpa_custom_metrics = [ - item { name: super.name + '_' + deployment.name + '_' + deployment_manifest.environment } - for item in hpa.custom_metrics -]; - -local basename = chart.full_service_name(deployment.name); -local isHpaEnabled = hpa.type == vars.deployment.hpa.type.metrics; -local name = if isHpaEnabled then - basename -else - basename + '-disabled'; - -{ - apiVersion: 'autoscaling/v2beta2', - kind: 'HorizontalPodAutoscaler', - metadata: { - name: name, - labels: common.labels, - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations + { - [std.format('metric-config.external.prometheus-query.prometheus/%s', metric.name)]: metric.query - for metric in hpa_custom_metrics - }, - }, - spec: { - maxReplicas: hpa.maxReplicas, - minReplicas: if hpa.minReplicas == 0 then 1 else hpa.minReplicas, - metrics: [ - { - resource: { - name: metric.name, - target: { - averageUtilization: metric.threshold, - type: 'Utilization', - }, - }, - type: 'Resource', - } - for metric in hpa.metrics - ] + [ - { - external: { - metric: { - name: 'prometheus-query', - selector: { - matchLabels: { - 'query-name': metric.name, - }, - }, - }, - target: { - type: 'Value', - value: metric.threshold, - }, - }, - type: 'External', - } - for metric in hpa_custom_metrics - ], - scaleTargetRef: util.hpa_scale_target_ref(deployment.name, deployment.controller, !isHpaEnabled), - }, -} diff --git a/templates/ingress.jsonnet b/templates/ingress.jsonnet deleted file mode 100644 index ef700e6c..00000000 --- a/templates/ingress.jsonnet +++ /dev/null @@ -1,189 +0,0 @@ -//Imports -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local load_balancer_util = import 'load_balancer_util.jsonnet'; -local namespace_values = import 'namespace_values.jsonnet'; -local port_map = import 'port_map.jsonnet'; -local util = import 'util.jsonnet'; -local flink = deployment_manifest.flink; -local sandbox = import './sandbox/main.jsonnet'; -local isSandbox = util.is_sandbox(deployment_manifest.environment); -local vars = import 'vars.jsonnet'; -local isflinkJob = std.objectHas(deployment_manifest, 'flink'); -local loadBalancers = if isflinkJob then deployment_manifest.flink.loadBalancers else deployment_manifest.deployment.loadBalancers; -local namespace = if isflinkJob then deployment_manifest.flink.namespace else deployment_manifest.deployment.namespace; -local exposedPorts = deployment_manifest.deployment.exposedPorts; - -local albScheme = { - internetFacing: 'internet-facing', - internal: 'internal', - cdn: 'internet-facing', - internetFacingRestricted: 'internet-facing', -}; - -local albTags = common.awsTags + if isSandbox then { - Environment: deployment_manifest.sandboxParams.source.environment, - Namespace: deployment_manifest.sandboxParams.source.namespace, -} else {}; - -local nginxClass(environment, serviceName) = '%s-%s-nginx' % [environment, serviceName]; - -local ingress_annotations(lbObject, clusterAnnotationValues, exposePortToLb=false, enableGrpc=false) = { - local subnetScheme = load_balancer_util.subnet_scheme(lbObject.accessPolicies), - local groupName = load_balancer_util.group_name(lbObject), - local ingressName = load_balancer_util.ingress_name(chart.full_service_name(deployment_manifest.name), lbObject), - - local sslCerts = clusterAnnotationValues.sslCert, - local certificateArns = std.join(',', std.set( - [sslCerts[util.get_certs(std.objectFieldsAll(sslCerts), lbObject.endpoint)]] + - [sslCerts[util.get_certs(std.objectFieldsAll(sslCerts), host.hostname)] for host in lbObject.redirects] + - [sslCerts[util.get_certs(std.objectFieldsAll(sslCerts), host)] for host in lbObject.additionalEndpoints] - )), - local redirect_annotations(destinationHost) = { ['alb.ingress.kubernetes.io/actions.redirect-%s' % i]: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301", "Host": "%(destinationHost)s","Path": "%(destinationPath)s"}}' % (lbObject.redirects[i] { destinationHost: destinationHost }) for i in std.range(0, std.length(lbObject.redirects) - 1) }, - - nginxLb: namespace_values.loadBalancer.annotations { - 'kubernetes.io/ingress.class': nginxClass(deployment_manifest.environment, deployment_manifest.name), - 'nginx.ingress.kubernetes.io/rewrite-target': '/', - }, - sharedAlbAcrossNamespace: common.annotations + namespace_values.loadBalancer.annotations { - local sortedPolicies = std.sort(lbObject.accessPolicies), - local sgs = [if accessPolicy in clusterAnnotationValues.securityGroups then clusterAnnotationValues.securityGroups[accessPolicy] for accessPolicy in sortedPolicies], - 'kubernetes.io/ingress.class': 'alb', - 'alb.ingress.kubernetes.io/target-type': 'ip', - 'alb.ingress.kubernetes.io/listen-ports': load_balancer_util.listener_ports(lbObject), - 'alb.ingress.kubernetes.io/certificate-arn': certificateArns, - 'alb.ingress.kubernetes.io/actions.ssl-redirect': '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}', - } - + ( - if load_balancer_util.target_group_attribute_list(lbObject) != null then { - 'alb.ingress.kubernetes.io/target-group-attributes': load_balancer_util.target_group_attribute_list(lbObject), - } else {} - ) - + (if subnetScheme == 'internetFacing' then { - 'alb.ingress.kubernetes.io/ip-address-type': 'dualstack', // exclusive - } else {}) - + (if groupName == null then {} else { - 'alb.ingress.kubernetes.io/group.name': '%s' % groupName, - 'alb.ingress.kubernetes.io/group.order': lbObject.groupOrder, - }) - + redirect_annotations(lbObject.endpoint), - alb: common.annotations + namespace_values.loadBalancer.annotations { - 'kubernetes.io/ingress.class': 'alb', - 'alb.ingress.kubernetes.io/target-type': 'ip', - [if enableGrpc then 'alb.ingress.kubernetes.io/backend-protocol-version']: 'GRPC', - [if !lbObject['tls-1-1'] then 'alb.ingress.kubernetes.io/ssl-policy']: 'ELBSecurityPolicy-TLS-1-2-2017-01', - 'alb.ingress.kubernetes.io/listen-ports': load_balancer_util.listener_ports(lbObject, exposePortToLb), - 'alb.ingress.kubernetes.io/certificate-arn': certificateArns, - 'alb.ingress.kubernetes.io/scheme': albScheme[subnetScheme], - 'alb.ingress.kubernetes.io/security-groups': (load_balancer_util.security_group_list(lbObject.accessPolicies, clusterAnnotationValues.securityGroups, lbObject.extraSecurityGroups)) - + (if (subnetScheme == 'internetFacing' || subnetScheme == 'internetFacingRestricted') then (',' + clusterAnnotationValues.securityGroups.http) else ''), - 'alb.ingress.kubernetes.io/load-balancer-attributes': load_balancer_util.load_balancer_attribute_list(lbObject, namespace_values.loadBalancer.annotations, deployment_manifest.name), - 'alb.ingress.kubernetes.io/tags': 'Environment=%(Environment)s,Owner=%(Owner)s,Name=%(Name)s,Team=%(Team)s,Namespace=%(Namespace)s,Ingress=%(ingressName)s,Product=%(Product)s' % (albTags { ingressName: ingressName }), - [if !exposePortToLb then 'alb.ingress.kubernetes.io/actions.ssl-redirect']: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}', - } + redirect_annotations(lbObject.endpoint) - + ( - if load_balancer_util.target_group_attribute_list(lbObject) != null then { - 'alb.ingress.kubernetes.io/target-group-attributes': load_balancer_util.target_group_attribute_list(lbObject), - } else {} - ) - + (if subnetScheme in (clusterAnnotationValues.subnets) then { - 'alb.ingress.kubernetes.io/subnets': clusterAnnotationValues.subnets[subnetScheme], - } else {}) - + (if subnetScheme == 'internetFacing' then { - 'alb.ingress.kubernetes.io/ip-address-type': 'dualstack', - [if lbObject.webAcl != 'false' then 'alb.ingress.kubernetes.io/wafv2-acl-arn']: lbObject.webAcl, - } else {}) - + (if subnetScheme == 'internetFacingRestricted' then { - 'alb.ingress.kubernetes.io/ip-address-type': 'dualstack', - } else {}) - + (if subnetScheme == 'cdn' then { - 'alb.ingress.kubernetes.io/ip-address-type': 'dualstack', - 'external-dns.alpha.kubernetes.io/exclude': 'true', - } else {}) - + (if deployment_manifest.environment != vars.environments.prod then { - 'alb.ingress.kubernetes.io/group.name': std.join('-', [ingressName, namespace]), - 'alb.ingress.kubernetes.io/group.order': lbObject.groupOrder, - } else {}) - + (if lbObject.groupName != '' then { - 'alb.ingress.kubernetes.io/group.name': std.join('-', [ingressName, namespace]), - } else {}), -}[lbObject.type]; - - -//Filter alb & sharedAlbAcrossNamespace type of loadbalancer configurations -local filteredLbs = std.filter(function(lbObject) std.find(lbObject.type, ['alb', 'sharedAlbAcrossNamespace', 'nginxLb']) != [], loadBalancers); - -local ports = [ - { port: port_map.getPort('serviceport'), exposeToLoadBalancer: false, portFieldKey: 'number', enableGrpc: port_map.isGrpcEnabled('serviceport') }, - { port: port_map.getPort('secondary-service-port'), exposeToLoadBalancer: true, portFieldKey: 'number', enableGrpc: port_map.isGrpcEnabled('secondary-service-port') }, - { port: port_map.getPort(chart.full_service_name(deployment_manifest.name) + '-rest'), exposeToLoadBalancer: false, portFieldKey: 'name' }, -]; -local loadbalancerWithAllPorts = [ - lb + port - for lb in filteredLbs - for port in ports - if port.port != null -]; - -// this is to ensure only in case of new load balancers,( which will not have groupName as empty string ), exposed ingress is created -local isOldALB(lbObject) = lbObject.groupName == ''; - -local filteredLoadBalancerWithAllPorts = [ - lbObject - for lbObject in loadbalancerWithAllPorts - if !isOldALB(lbObject) || (isOldALB(lbObject) && !lbObject.exposeToLoadBalancer) -]; - -std.map( - //Generate ingress objects based on above filtered configurations - function(lbIndex) { - config:: { - lbObject: filteredLoadBalancerWithAllPorts[lbIndex], - subnetScheme: load_balancer_util.subnet_scheme($.config.lbObject.accessPolicies), - serviceName: if isflinkJob then (deployment_manifest.name + '-rest') else chart.full_service_name(deployment_manifest.name), - servicePort: $.config.lbObject.port, - exposePortToLoadBalancer: $.config.lbObject.exposeToLoadBalancer, - enableGrpc: $.config.lbObject.enableGrpc, - portFieldKey: $.config.lbObject.portFieldKey, - name: load_balancer_util.ingress_name(chart.full_service_name(deployment_manifest.name), $.config.lbObject, $.config.exposePortToLoadBalancer), - }, - assert std.length($.config.name) <= 253 : 'Ingress name must be less than 253 characters. name: %s' % $.config.name, - apiVersion: 'networking.k8s.io/v1', - kind: 'Ingress', - metadata: { - name: $.config.name, - labels: common.labels, - annotations: ingress_annotations($.config.lbObject, namespace_values.loadBalancer.annotations, $.config.exposePortToLoadBalancer, $.config.enableGrpc) + if isSandbox then sandbox.sandbox($.config).albIngress.annotations else {}, - namespace: namespace, - }, - spec: { - rules: [ - { - host: if $.config.lbObject.endpoint != null && $.config.lbObject.endpoint != '' then $.config.lbObject.endpoint else namespace_values.loadBalancer.fixedHostNames[deployment_manifest.name], - http: { - paths: (if $.config.exposePortToLoadBalancer then [] else load_balancer_util.http_redirect_config) - + load_balancer_util.weighted_path_config($.config.serviceName) - + (if isSandbox then sandbox.sandbox($.config).albIngress.host.paths else - (load_balancer_util.path_config($.config.serviceName, $.config.servicePort, $.config.portFieldKey))), - }, - }, - ] + [ - { - host: endpoint, - http: { - paths: if $.config.subnetScheme == 'internetFacing' || - $.config.subnetScheme == 'internetFacingRestricted' then - load_balancer_util.http_redirect_config - else - load_balancer_util.create_sandbox_or_standard_paths($.config, isSandbox, sandbox), - }, - } - for endpoint in $.config.lbObject.additionalEndpoints - ] + [load_balancer_util.redirect_config($.config.lbObject.redirects[i], 'redirect-%s' % i) for i in std.range(0, std.length($.config.lbObject.redirects) - 1)], - - }, - }, - - std.range(0, std.length(filteredLoadBalancerWithAllPorts) - 1) -) diff --git a/templates/kibana.jsonnet b/templates/kibana.jsonnet deleted file mode 100644 index 6fb3c7e6..00000000 --- a/templates/kibana.jsonnet +++ /dev/null @@ -1,60 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; - -if deployment_manifest.deployment.elasticSearch.kibana != null then { - apiVersion: 'kibana.k8s.elastic.co/v1', - kind: 'Kibana', - metadata: { - name: deployment.elasticSearch.instance.instanceName + '-kibana', - namespace: deployment_manifest.environment + '-datastores', - labels: deployment.elasticSearch.kibanaLabels, - annotations: common.annotations, - }, - spec: { - version: deployment.elasticSearch.kibanaVersion, - image: deployment.elasticSearch.kibanaImage, - config: { - 'xpack.monitoring.enabled': true, - 'xpack.monitoring.ui.enabled': true, - 'xpack.monitoring.kibana.collection.enabled': true, - 'server.publicBaseUrl': 'https://' + deployment.elasticSearch.kibana, - }, - http: { - tls: { - selfSignedCertificate: { - disabled: true, - }, - }, - }, - count: 2, - elasticsearchRef: { - name: deployment.elasticSearch.instance.instanceName + '-elasticsearch', - }, - podTemplate: { - metadata: { - labels: deployment.elasticSearch.kibanaLabels, - }, - spec: { - nodeSelector: deployment.elasticSearch.esNodeSelector, - tolerations: deployment.elasticSearch.esTolerations, - containers: [ - { - name: 'kibana', - resources: { - requests: { - memory: '1Gi', - cpu: 0.5, - }, - limits: { - memory: '4Gi', - cpu: 2, - }, - }, - }, - ], - }, - }, - }, -} diff --git a/templates/kibana_ingress_endpoint.jsonnet b/templates/kibana_ingress_endpoint.jsonnet deleted file mode 100644 index e0416cf4..00000000 --- a/templates/kibana_ingress_endpoint.jsonnet +++ /dev/null @@ -1,83 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local namespace_values = import 'namespace_values.jsonnet'; -local load_balancer_util = import 'load_balancer_util.jsonnet'; -local util = import 'util.jsonnet'; - -local albTags = common.awsTags; -local ingressName = deployment.elasticSearch.instance.instanceName + '-kibana'; -local groupName = '%s-datastores-services-alb' % deployment_manifest.environment; -local annotations = namespace_values.loadBalancer.annotations; -local securityGroups = std.join(',', [ - annotations.securityGroups.internal, - annotations.securityGroups.officeIp, -]); -local lbObject = { - idleTimeout: 60, - accessPolicies: ['internal'], - accessLog: true, -}; -local subnetScheme = load_balancer_util.subnet_scheme(lbObject.accessPolicies); - -if deployment_manifest.deployment.elasticSearch.kibana != null then { - apiVersion: 'networking.k8s.io/v1', - kind: 'Ingress', - metadata: { - name: deployment.elasticSearch.instance.instanceName + '-kibana', - namespace: deployment_manifest.environment + '-datastores', - annotations: common.annotations { - 'kubernetes.io/ingress.class': 'alb', - 'alb.ingress.kubernetes.io/target-type': 'ip', - 'alb.ingress.kubernetes.io/ssl-policy': 'ELBSecurityPolicy-TLS-1-2-2017-01', - 'alb.ingress.kubernetes.io/listen-ports': load_balancer_util.listener_ports(lbObject), - 'alb.ingress.kubernetes.io/certificate-arn': annotations.sslCert[util.get_certs(std.objectFieldsAll(annotations.sslCert), deployment_manifest.deployment.elasticSearch.kibana)], - 'alb.ingress.kubernetes.io/scheme': 'internal', - 'alb.ingress.kubernetes.io/security-groups': securityGroups, - 'alb.ingress.kubernetes.io/load-balancer-attributes': load_balancer_util.load_balancer_attribute_list(lbObject, namespace_values.loadBalancer.annotations, groupName), - 'alb.ingress.kubernetes.io/tags': 'Name=shared-alb-%(name)s,Ingress=shared-alb-%(name)s,Owner=shared,Team=Shared,Product=%(Product)s,Environment=%(Environment)s' % (albTags { name: groupName }), - 'alb.ingress.kubernetes.io/actions.ssl-redirect': '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}', - 'alb.ingress.kubernetes.io/group.name': '%s' % groupName, - } - + ( - if load_balancer_util.subnet_scheme(lbObject.accessPolicies) in (annotations.subnets) then { - 'alb.ingress.kubernetes.io/subnets': annotations.subnets[subnetScheme], - } else {} - ), - }, - spec: { - rules: [ - { - host: deployment_manifest.deployment.elasticSearch.kibana, - http: { - paths: [ - { - backend: { - service: { - name: 'ssl-redirect', - port: { - name: 'use-annotation', - }, - }, - }, - pathType: 'ImplementationSpecific', - path: '/*', - }, - { - pathType: 'ImplementationSpecific', - backend: { - service: { - name: deployment.elasticSearch.instance.instanceName + '-kibana' + '-kb-http', - port: { - number: 5601, - }, - }, - }, - }, - ], - }, - }, - ], - }, -} diff --git a/templates/load_balancer_util.jsonnet b/templates/load_balancer_util.jsonnet deleted file mode 100644 index e226e5c6..00000000 --- a/templates/load_balancer_util.jsonnet +++ /dev/null @@ -1,142 +0,0 @@ -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local util = import 'util.jsonnet'; -local vars = import 'vars.jsonnet'; -local isSandbox = util.is_sandbox(deployment_manifest.environment); - -local alias(type) = if type == 'sharedalbacrossnamespace' then 'sharedalb' else type; - -{ - // Creates a comma separated list of security groups - security_group_list(accessPolicies, securityGroups, extraSecurityGroups):: - local accessPolicySecurityGroups = [if accessPolicy in securityGroups then securityGroups[accessPolicy] for accessPolicy in accessPolicies]; - local extraSGs = if std.objectHas(deployment_manifest.deployment, 'securityGroup') then std - .flattenArrays([if std.objectHas(sg, 'ids') then sg.ids for sg in deployment_manifest - .deployment.securityGroup]) else []; - std.join(',', accessPolicySecurityGroups + extraSGs), - - // Determines kind of subnet(internal or internetFacing or cdn) to use based on access policy. - subnet_scheme(accessPolicies):: - local scheme = std.setInter(std.set(accessPolicies), ['internal', 'internetFacing', 'internetFacingRestricted', 'cdn']); - assert std.length(scheme) == 1 : 'ValidationError: accessPolicies can only contain one out of internal, internetFacing, interetFacingRestricted & cdn'; - { internal: 'internal', internetFacing: 'internetFacing', internetFacingRestricted: 'internetFacingRestricted', cdn: 'cdn' }[scheme[0]], - - // Returns true if application is using aws application load balancer - is_using_lb(lbObjects, lbName):: - std.length(std.filter(function(lbObject) lbObject.type == lbName, lbObjects)) > 0, - - // Returns group name for sharedAlbAcrossNamespace if any - group_name(lbObject):: - if lbObject.groupName != null && lbObject.groupName != '' then - lbObject.groupName - else null, - - // Returns true if application is using aws target groups - is_using_tg(lbObjects):: - std.length(std.filter(function(lbObject) std.find(lbObject.type, ['alb', 'sharedAlbAcrossNamespace']) != [], lbObjects)) > 0, - - ingress_name(full_service_name, lbObject, expose=false):: - local name = if lbObject.name != null && lbObject.name != '' then - full_service_name + '-' + alias(std.asciiLower(lbObject.type)) + '-' + std.asciiLower(lbObject.name) - else - full_service_name + '-' + alias(std.asciiLower(lbObject.type)); - local finalName = if expose then name + '-exposed' else name; - finalName, - - alb_ingress_name(full_service_name):: - self.ingress_name(full_service_name, { type: 'alb', name: null }), - - load_balancer_attribute_list(lbObject, namespace_annotations, s3_key_prefix):: - local idleTimeout = 'idle_timeout.timeout_seconds=%s' % lbObject.idleTimeout; - local baseAttributes = if namespace_annotations.deletionProtection then idleTimeout + ',deletion_protection.enabled=true' else idleTimeout; - local accessLogAttributes = 'access_logs.s3.enabled=true,access_logs.s3.bucket=%s,access_logs.s3.prefix=%s' % [namespace_annotations.accessLogBucket, s3_key_prefix]; - std.join(',', [ - baseAttributes, - if lbObject.accessLog then accessLogAttributes, - ],), - - target_group_attribute_list(lbObject):: - local slowStartDurationAttribute = 'slow_start.duration_seconds=%s' % lbObject.slowStartDuration; - local sticknessAttribute = 'stickiness.enabled=true,stickiness.lb_cookie.duration_seconds=%s' % lbObject.stickinessCookieDuration; - local tg_annotation = [ - if lbObject.slowStartDuration > 0 then slowStartDurationAttribute, - if lbObject.stickiness then sticknessAttribute, - ]; - std.join(',', std.prune(tg_annotation)), - - //Determines listener-ports to be added to the load-balaner - listener_ports(lbObject, exposeToLoadBalancer=false):: - local subnetScheme = $.subnet_scheme(lbObject.accessPolicies); - if exposeToLoadBalancer then - if lbObject.type == 'alb' then '[{"HTTPS": %s}]' % lbObject.port - else error 'ValidationError: secondary port can only be used with alb. Please change the loadbalancer type' - else - '[{ "HTTPS": 443 },{"HTTP": 80}]', - - //Returns path to be added to alb to enable HTTP to HTTPS redirection - http_redirect_config:: [{ - path: '/*', - pathType: 'ImplementationSpecific', - backend: { - service: { - name: 'ssl-redirect', - port: { - name: 'use-annotation', - }, - }, - }, - }], - - redirect_config(host, actionNaem):: { - host: host.hostname, - http: { - paths: [{ - path: host.path, - pathType: 'ImplementationSpecific', - backend: { - service: { - name: actionNaem, - port: { - name: 'use-annotation', - }, - }, - }, - }], - }, - }, - - weighted_path_config(serviceName):: if 'flink' in deployment_manifest then [] - else (if (deployment_manifest.deployment.controller == vars.rolloutController && deployment_manifest.deployment.strategy != vars.defaultDeploymentStrategy && !isSandbox) then [{ - path: '/*', - pathType: 'ImplementationSpecific', - backend: { - service: { - name: serviceName, - port: { - name: 'use-annotation', - }, - }, - }, - }] else []), - - path_config(serviceName, servicePort, portFieldKey='number'):: - [ - { - pathType: 'ImplementationSpecific', - backend: { - service: { - name: serviceName, - port: { - [portFieldKey]: servicePort, - }, - }, - }, - }, - ], - - create_sandbox_or_standard_paths(config, isSandboxEnabled=false, sandbox={}):: ( - if isSandboxEnabled then - sandbox.sandbox(config).albIngress.host.paths - else - $.path_config(config.serviceName, config.servicePort) - ), -} diff --git a/templates/main.jsonnet b/templates/main.jsonnet deleted file mode 100644 index d13b745e..00000000 --- a/templates/main.jsonnet +++ /dev/null @@ -1,97 +0,0 @@ -local common_api_gateways = import 'common_api_gateway.jsonnet'; -local configmap = import 'configmap.jsonnet'; -local cron_hpa_autoscaler = import 'cron_hpa_autoscaler.jsonnet'; -local default_alerts = import 'default_alerts.jsonnet'; -local deployment = import 'deployment.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local rollout = import 'rollout.jsonnet'; -local hpa = import 'hpa.jsonnet'; -local ingresses = import 'ingress.jsonnet'; -local kibana = import 'kibana.jsonnet'; -local kibana_ingress_endpoint = import 'kibana_ingress_endpoint.jsonnet'; -local pdb = import 'pdb.jsonnet'; -local perf_utility = import 'perf_utility.jsonnet'; -local rollout_analysis_template = import 'rollout_analysis_template.jsonnet'; -local sandbox = import 'sandbox/main.jsonnet'; -local secret = import 'secret.jsonnet'; -local security_group = import 'security_group.jsonnet'; -local service = import 'service.jsonnet'; -local service_monitor = import 'service_monitor.jsonnet'; -local sidecar = import 'sidecar.jsonnet'; -local cron_hpa_autoscaler = import 'cron_hpa_autoscaler.jsonnet'; -local elastic_search_secrets = import 'elasticsearch_secrets.jsonnet'; -local elastic_search = import 'elastic_search.jsonnet'; -local kibana = import 'kibana.jsonnet'; -local kibana_ingress_endpoint = import 'kibana_ingress_endpoint.jsonnet'; -local elasticsearch_sm_secrets = import 'elasticsearch_sm_secrets.jsonnet'; -local elasticsearch_servicemonitor = import 'elasticsearch_servicemonitor.jsonnet'; -local elasticsearch_alerts_default = import 'elasticsearch_alerts_default.jsonnet'; -local elasticsearch_snapshots = import 'elasticsearch_snapshots.jsonnet'; -local dynamic_configuration = import 'dynamic_configuration.jsonnet'; -local perf_utility = import 'perf_utility.jsonnet'; -local vpa = import 'vpa.jsonnet'; -local efs_pvc = import 'efs_persistent_volume_claim.jsonnet'; -local common_api_gateways = import 'common_api_gateway.jsonnet'; -local sandbox = import 'sandbox/main.jsonnet'; -local util = import 'util.jsonnet'; -local isSandbox = util.is_sandbox(deployment_manifest.environment); -local flink_deployment = import 'flink_deployment.jsonnet'; -local flink_session_job = import 'flink_session_job.jsonnet'; -local flink_service_account = import 'flink_service_account.jsonnet'; -local flink_role_binding = import 'flink_role_binding.jsonnet'; -local flink_default_alerts = import 'flink_default_alerts.jsonnet'; -local isflinkJob = std.objectHas(deployment_manifest, 'flink'); - -if isflinkJob then - ({ - '0_secret.json': secret, - '0_0_flink_deployment.json': flink_deployment, - '0_1_flink_session_job.json': flink_session_job, - '0_2_flink_service_account.json': flink_service_account, - '0_3_flink_role_binding.json': flink_role_binding, - '0_4_flink_default_alerts.json': flink_default_alerts, - } + { ['5_%s_ingress.json' % index]: ingresses[index] for index in std.range(0, std.length(ingresses) - 1) }) -else ({ - '0_secret.json': secret, - '1_configmap.json': configmap, - '2_sidecar.json': sidecar, - '3_service.json': service, - '4_deployment.json': deployment, - '4_rollout.json': rollout, - '4_0_rollout_analysis_template.json': rollout_analysis_template, - '6_pdb.json': pdb, - '7_service_monitor.json': service_monitor, - '8_default_alerts.json': default_alerts, - '9_hpa.json': hpa, - '11_cron_hpa_autoscaler.json': cron_hpa_autoscaler, - '12_elastic_search_secrets.json': elastic_search_secrets, - '13_elastic_search.json': elastic_search, - '14_kibana.json': kibana, - '15_kibana_ingress_endpoint.json': kibana_ingress_endpoint, - '16_elasticsearch_sm_secrets.json': elasticsearch_sm_secrets, - '17_elasticsearch_servicemonitor.json': elasticsearch_servicemonitor, - '18_elasticsearch_alerts_default.json': elasticsearch_alerts_default, - '19_elasticsearch_snapshots.json': elasticsearch_snapshots, - '20_dynamic_configuration.json': dynamic_configuration, - '21_perf_utility.json': perf_utility, - '22_vpa.json': vpa, - '23_efs_pvc.json': efs_pvc, - }) - + - (if isSandbox then { - '0_0_namespace.json': sandbox.sandbox().namespace, - '0_1_iam_role.json': sandbox.sandbox().iamRole, - '30_role_binding.json': sandbox.sandbox().roleBinding, - '31_access_role_binding.json': sandbox.sandbox().accessRoleBinding, - '32_access_role.json': sandbox.sandbox().accessRole, - } else {}) - + - (if ingresses != null then - { ['5_%s_ingress.json' % index]: ingresses[index] for index in std.range(0, std.length(ingresses) - 1) } - + - if security_group != null then - { ['10_%s_security_group.json' % index]: security_group[index] for index in std.range(0, std.length - (security_group) - 1) } else {}) - + - (if common_api_gateways != null then - { ['23_%s_common_api_gateways.json' % index]: common_api_gateways[0].items[index] for index in std.range(0, std.length(common_api_gateways[0].items) - 1) }) diff --git a/templates/manifest_util.jsonnet b/templates/manifest_util.jsonnet deleted file mode 100644 index d1b886dd..00000000 --- a/templates/manifest_util.jsonnet +++ /dev/null @@ -1,17 +0,0 @@ -{ - is_alert_defined(deployment, alertName):: - if ('alerts' in deployment && alertName in deployment.alerts) then true else false, - - is_database_present(deploymentManifest):: - if ('extraResources' in deploymentManifest && deploymentManifest.extraResources != null) then - if ('database' in deploymentManifest.extraResources) then - local database = deploymentManifest.extraResources.database; - 'instanceName' in database && database.instanceName != '' - else false - else false, - is_dynamic_config_present(deploymentManifest):: - if ('dynamicConfiguration' in deploymentManifest && deploymentManifest.dynamicConfiguration != null && deploymentManifest.dynamicConfiguration != []) then true else false, - - is_custom_slack_channel_enabled(alert):: - if ('slackChannel' in alert && alert.slackChannel != null && alert.slackChannel != '') then true else false, -} diff --git a/templates/namespace_values.jsonnet b/templates/namespace_values.jsonnet deleted file mode 100644 index dca39ab1..00000000 --- a/templates/namespace_values.jsonnet +++ /dev/null @@ -1,19 +0,0 @@ -local cluster_values = import 'cluster_values.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; - -assert deployment_manifest.cluster in cluster_values : - 'ValidationError: Unrecognized cluster - %s' % deployment_manifest.cluster; - -local cluster_config = cluster_values[deployment_manifest.cluster]; -local manifest_namespace = if 'flink' in deployment_manifest then deployment_manifest.flink.namespace else deployment_manifest.deployment.namespace; - - -// Use default namespace values for a cluster if specific namespace values not present -local namespace_values = - if manifest_namespace in cluster_config - then - cluster_config[manifest_namespace] - else - cluster_config.default; - -namespace_values diff --git a/templates/pdb.jsonnet b/templates/pdb.jsonnet deleted file mode 100644 index efb1d588..00000000 --- a/templates/pdb.jsonnet +++ /dev/null @@ -1,20 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; - -if deployment_manifest.deployment.instance.count > 1 then { - apiVersion: 'policy/v1beta1', - kind: 'PodDisruptionBudget', - metadata: { - name: chart.full_service_name(deployment_manifest.deployment.name) + '-pdb', - labels: common.labels, - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations, - }, - spec: { - maxUnavailable: '15%', - selector: { - matchLabels: common.matchLabels, - }, - }, -} diff --git a/templates/perf_utility.jsonnet b/templates/perf_utility.jsonnet deleted file mode 100644 index e17421cf..00000000 --- a/templates/perf_utility.jsonnet +++ /dev/null @@ -1,289 +0,0 @@ -local chart = import 'chart.jsonnet'; -local cluster_values = import 'cluster_values.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local namespace_values = import 'namespace_values.jsonnet'; -local util = import 'util.jsonnet'; -local load_balancer_util = import 'load_balancer_util.jsonnet'; - -local albTags = common.awsTags; -local ingressName = deployment.name + '-mock-server'; -local postgresServiceName = deployment.name + '-postgres-server'; -local mockEndpointName = deployment.name + '-perf-mock'; -local postgresEndpointName = deployment.name + '-perf-postgres'; -local domainEndpoint = cluster_values.perfDomainEndpoint[deployment_manifest.infraVertical]; -local lbObject = { - idleTimeout: 60, - accessPolicies: ['internal'], - accessLog: true, -}; -local subnetScheme = load_balancer_util.subnet_scheme(lbObject.accessPolicies); -local annotations = namespace_values.loadBalancer.annotations; -local groupName = 'perf-internal'; -local securityGroups = std.join(',', [ - annotations.securityGroups.internal, - annotations.securityGroups.officeIp, -]); - -if deployment_manifest.environment == 'perf' && (deployment_manifest.deployment.perfUtility.mockServerEnabled || deployment_manifest.deployment.perfUtility.postgresServerEnabled) == true then { - apiVersion: 'v1', - kind: 'List', - items: - (if deployment_manifest.deployment.perfUtility.mockServerEnabled then [ - { - apiVersion: 'apps/v1', - kind: 'Deployment', - metadata: { - name: deployment.name + '-mock-server', - labels: common.perfMockServerLabels, - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations, - }, - spec: { - progressDeadlineSeconds: 1500, - selector: { - matchLabels: { - app: chart.service_name, - release: deployment.name + '-mock-server', - }, - }, - template: { - metadata: { - labels: common.perfMockServerLabels, - }, - spec: { - containers: [{ - name: 'mock-server', - image: deployment_manifest.deployment.perfUtility.mockServerImage, - imagePullPolicy: 'IfNotPresent', - resources: { - requests: { - memory: '2Gi', - cpu: '1', - }, - limits: { - memory: '2Gi', - cpu: '1', - }, - }, - }], - }, - }, - }, - }, - { - apiVersion: 'v1', - kind: 'Service', - metadata: { - name: deployment.name + '-mock-server', - labels: common.perfMockServerLabels, - namespace: deployment_manifest.deployment.namespace, - }, - spec: { - selector: { - app: chart.service_name, - release: deployment.name + '-mock-server', - }, - type: 'ClusterIP', - ports: [ - { - name: 'service-port', - port: 1080, - protocol: 'TCP', - targetPort: 1080, - }, - ], - }, - }, - { - apiVersion: 'networking.k8s.io/v1', - kind: 'Ingress', - metadata: { - name: deployment.name + '-mock-server', - annotations: { - 'kubernetes.io/ingress.class': 'alb', - 'alb.ingress.kubernetes.io/target-type': 'ip', - 'alb.ingress.kubernetes.io/ssl-policy': 'ELBSecurityPolicy-TLS-1-2-2017-01', - 'alb.ingress.kubernetes.io/listen-ports': load_balancer_util.listener_ports(lbObject), - 'alb.ingress.kubernetes.io/certificate-arn': annotations.sslCert[util.get_certs(std.objectFieldsAll(annotations.sslCert), mockEndpointName + domainEndpoint)], - 'alb.ingress.kubernetes.io/scheme': 'internal', - 'alb.ingress.kubernetes.io/security-groups': securityGroups, - 'alb.ingress.kubernetes.io/load-balancer-attributes': load_balancer_util.load_balancer_attribute_list(lbObject, namespace_values.loadBalancer.annotations, groupName), - 'alb.ingress.kubernetes.io/tags': 'Name=shared-alb-%(name)s,Ingress=shared-alb-%(name)s,Owner=shared,Team=Shared,Product=%(Product)s,Environment=%(Environment)s' % (albTags { name: groupName }), - 'alb.ingress.kubernetes.io/actions.ssl-redirect': '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}', - 'alb.ingress.kubernetes.io/group.name': '%s' % groupName, - } - + ( - if load_balancer_util.subnet_scheme(lbObject.accessPolicies) in (annotations.subnets) then { - 'alb.ingress.kubernetes.io/subnets': annotations.subnets[subnetScheme], - } else {} - ), - namespace: deployment_manifest.deployment.namespace, - }, - spec: { - rules: [ - { - host: mockEndpointName + domainEndpoint, - http: { - paths: [ - { - pathType: 'ImplementationSpecific', - backend: { - service: { - name: 'ssl-redirect', - port: { - name: 'use-annotation', - }, - }, - }, - path: '/*', - }, - { - pathType: 'ImplementationSpecific', - backend: { - service: { - name: deployment.name + '-mock-server', - port: { - number: 1080, - }, - }, - }, - }, - ], - }, - }, - ], - }, - }, - ] else []) + - (if deployment_manifest.deployment.perfUtility.postgresServerEnabled then [ - { - apiVersion: 'v1', - kind: 'Secret', - metadata: { - name: deployment.name + '-postgres-secret', - labels: common.perfPostgresServerLabels, - namespace: deployment_manifest.deployment.namespace, - }, - type: 'Opaque', - data: { password: 'cG9zdGdyZXNwZXJmcGFzc3dvcmQK' }, - }, - { - apiVersion: 'v1', - kind: 'PersistentVolumeClaim', - metadata: { - name: deployment.name + '-postgres-storage', - labels: common.perfPostgresServerLabels, - namespace: deployment_manifest.deployment.namespace, - }, - spec: { - accessModes: ['ReadWriteOnce'], - resources: { - requests: { - storage: deployment_manifest.deployment.perfUtility.postgresDbConfig.storage, - }, - }, - storageClassName: 'gp2', - }, - }, - { - apiVersion: 'apps/v1', - kind: 'Deployment', - metadata: { - name: deployment.name + '-postgres-server', - labels: common.perfPostgresServerLabels, - namespace: deployment_manifest.deployment.namespace, - }, - spec: { - progressDeadlineSeconds: 1500, - selector: { - matchLabels: { - app: chart.service_name, - release: deployment.name + '-postgres-server', - }, - }, - template: { - metadata: { - labels: common.perfPostgresServerLabels, - }, - spec: { - containers: [{ - name: 'postgres', - image: deployment_manifest.deployment.perfUtility.postgresServerImage, - imagePullPolicy: 'IfNotPresent', - env: [ - { - name: 'POSTGRES_PASSWORD', - valueFrom: { - secretKeyRef: { - name: deployment.name + '-postgres-secret', - key: 'password', - }, - }, - }, - { - name: 'PGDATA', - value: '/var/lib/postgresql/data/pgdata', - }, - ], - resources: { - requests: { - memory: deployment_manifest.deployment.perfUtility.postgresDbConfig.memory, - cpu: deployment_manifest.deployment.perfUtility.postgresDbConfig.cpu, - }, - limits: { - memory: deployment_manifest.deployment.perfUtility.postgresDbConfig.memory, - cpu: deployment_manifest.deployment.perfUtility.postgresDbConfig.cpu, - }, - }, - volumeMounts: [ - { - name: deployment.name + '-postgres-storage', - mountPath: '/var/lib/postgresql/data', - }, - ], - }], - volumes: [ - { - name: deployment.name + '-postgres-storage', - persistentVolumeClaim: { - claimName: deployment.name + '-postgres-storage', - }, - }, - ], - }, - }, - }, - }, - { - apiVersion: 'v1', - kind: 'Service', - metadata: { - name: deployment.name + '-postgres-server', - labels: common.perfPostgresServerLabels, - annotations: { - 'external-dns.alpha.kubernetes.io/hostname': postgresEndpointName + domainEndpoint, - 'service.beta.kubernetes.io/aws-load-balancer-internal': '0.0.0.0/0', - 'service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags': 'Environment=%(Environment)s,Owner=%(Owner)s,Name=%(Name)s,Team=%(Team)s,Product=%(Product)s' % (albTags { ingressName: postgresServiceName }), - }, - namespace: deployment_manifest.deployment.namespace, - }, - spec: { - selector: { - app: chart.service_name, - release: deployment.name + '-postgres-server', - }, - type: 'LoadBalancer', - ports: [ - { - name: 'service-port', - port: 5432, - protocol: 'TCP', - targetPort: 5432, - }, - ], - }, - }, - ] else []), -} diff --git a/templates/pod_template.jsonnet b/templates/pod_template.jsonnet deleted file mode 100644 index 5b4da4bb..00000000 --- a/templates/pod_template.jsonnet +++ /dev/null @@ -1,363 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment_util = import 'deployment_util.jsonnet'; -local health_check_values = import 'health_check_values.jsonnet'; -local port_map = import 'port_map.jsonnet'; -local util = import 'util.jsonnet'; -local vars = import 'vars.jsonnet'; -local environments = vars.environments; -local deployment = deployment_manifest.deployment; -local environment = deployment_manifest.environment; -local readinessCheck = deployment.healthChecks.readinessCheck; -local livenessCheck = deployment.healthChecks.livenessCheck; -local startupProbe = deployment.healthChecks.startupProbe; -local exposedPorts = deployment_manifest.deployment.exposedPorts; -local manifest_util = import 'manifest_util.jsonnet'; -local namespace_values = import 'namespace_values.jsonnet'; -local vars = import 'vars.jsonnet'; -local image = util.get_image(deployment.image, environment); -assert image != 'null' : '[IMAGE or deployment.image] cannot be null'; - -local isSandbox = util.is_sandbox(environment); -local sandbox = import 'sandbox/main.jsonnet'; -local sandboxConfig = sandbox.sandbox(); - -// Conditions to check if heap-dump sidecar has to be enabled or not -local isEfsNeeded = deployment_util.isEfsNeeded(deployment); -local isFsxNeeded = deployment_util.isFsxNeeded(deployment); -local mandatoryHeapDumpString = '-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/dumps'; -local errorLogFileString = '-XX:ErrorFile=/dumps/hs_err_pid%p.log'; -local envKeys = [e.name for e in deployment_manifest.environmentVariables]; -local jvmOptionsExists = std.length(std.find('JVM_OPTS', envKeys)); -local isSwApmEnabled = deployment_manifest.isSwApmEnabled; -local jvmParameter = [e for e in deployment_manifest.environmentVariables if std.toString(e.name) == 'JVM_OPTS'][0]; -local heapDumpEnabled = if !isSandbox && (jvmOptionsExists > 0 && (std.length(std.findSubstr(mandatoryHeapDumpString, std.toString(jvmParameter.value))) > 0 - || std.length(std.findSubstr(errorLogFileString, std.toString(jvmParameter.value))) > 0)) then true else false; - -//# Sandbox - -// GPU -local isGPUEnabled = if deployment.instance.gpu == 0 then false else true; - -// Required to form S3 bucket name for heap-dumps -local bucketEnvironment = if deployment_manifest.environment == environments.prod then environments.prod else 'nonprod'; -local bucketName = 'java-heap-dumps-' + deployment_manifest.infraVertical + '-' + bucketEnvironment; -local hasEnvironmentFile = if 'environmentFile' in deployment then true else false; - -local needsAWSAccess = if util.is_field_present(deployment_manifest.extraResources, 'aws_access') - && util.is_field_present(deployment_manifest.extraResources.aws_access, 'policies') - && std.length(deployment_manifest.extraResources.aws_access.policies) > 0 then true else false; - -local roleName = (if ('roleName' in deployment_manifest.extraResources.aws_access && deployment_manifest.extraResources.aws_access.roleName != '') then deployment_manifest.extraResources.aws_access.roleName else chart.full_service_name(deployment.name)) + '-' + deployment_manifest.environment; - -local istioInboundPortsAnnotation = if deployment.disableIstio then - { 'sidecar.istio.io/inject': 'false' } -else - { - 'traffic.sidecar.istio.io/excludeInboundPorts': std.join(',', std.map(function(exposedPort) std.toString(exposedPort.port), exposedPorts)), - 'traffic.sidecar.istio.io/includeInboundPorts': '*', - }; - -local injectSwAgent(isSwApmEnabled) = ( - if isSwApmEnabled then [ - { - name: 'agent-container', - image: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/skywalking-java-agent:8.7.0-alpine', - volumeMounts: [ - { - name: 'skywalking-agent', - mountPath: '/agent', - }, - ], - command: [ - '/bin/sh', - ], - args: [ - '-c', - 'cp -R /skywalking/agent /agent/ && cp /skywalking/agent/optional-plugins/apm-kotlin-coroutine-plugin-8.7.0.jar /agent/agent/plugins', - ], - securityContext: { - runAsUser: 4000, - }, - }, - ] - else null -); - -local topologicalSpreadConstraints = [ - { - maxSkew: 1, - topologyKey: 'topology.kubernetes.io/zone', - whenUnsatisfiable: 'DoNotSchedule', - labelSelector: { - matchLabels: common.matchLabels, - }, - }, -]; - -{ - metadata: { - labels: common.labels, - annotations: common.annotations + istioInboundPortsAnnotation, - }, - spec: { - [if isSandbox then 'securityContext']: sandboxConfig.securityContext, - initContainers: injectSwAgent(isSwApmEnabled), - [if deployment_manifest.environment == environments.prod then 'topologySpreadConstraints' else null]: topologicalSpreadConstraints, - [if isGPUEnabled then 'nodeSelector']: deployment.instance.gpuNodeSelector, - [if isGPUEnabled then 'tolerations']: deployment.instance.gpuTolerations, - containers: - (if heapDumpEnabled then [{ - name: 'push-heap-dump', - image: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/java-heap-dump-manager:v7d6dad2b5a2431412b8183c9707f93b5dcb05287', - resources: { - limits: { - memory: '128Mi', - cpu: '100m', - }, - requests: { - memory: '128Mi', - cpu: '100m', - }, - }, - env: [ - { - name: 'AWS_DEFAULT_REGION', - value: 'ap-south-1', - }, - { - name: 'AWS_SHARED_CREDENTIALS_FILE', - value: '/meta/aws-iam/credentials.process', - }, - { - name: 'AWS_CREDENTIAL_PROFILES_FILE', - value: '/meta/aws-iam/credentials', - }, - { - name: 'SERVICE_NAME', - value: chart.full_service_name(deployment.name), - }, - { - name: 'S3_BUCKET', - value: if 'heapDumpBucket' in namespace_values then namespace_values.heapDumpBucket else bucketName, - }, - { - name: 'ENVIRONMENT', - value: deployment_manifest.environment, - }, - ], - volumeMounts: [ - { - name: 'aws-iam-credentials-heap-dump', - mountPath: '/meta/aws-iam', - readOnly: true, - }, - { - name: 'heap-dumps', - mountPath: '/dumps', - }, - ], - }] else []) + - [ - { - env: [ - { - name: e.name, - valueFrom: { - secretKeyRef: { - name: chart.full_service_name(deployment.name) + '-secret', - key: e.name, - }, - }, - } - for e in deployment_manifest.environmentVariables - ] + (if needsAWSAccess && namespace_values.zalandoEnabled then [ - { - name: 'AWS_SHARED_CREDENTIALS_FILE', - value: '/meta/aws-iam/credentials.process', - }, - { - name: 'AWS_CREDENTIAL_PROFILES_FILE', - value: '/meta/aws-iam/credentials', - }, - ] else []) - // Adding md5 to make sure deployment is retrigerred if just values are changed - + [{ name: 'secretMd5', value: std.md5(std.toString(deployment_manifest.environmentVariables)) }] - + (if 'environmentFile' in deployment then - [{ name: 'environmentFileMd5', value: std.md5(std.toString(deployment.environmentFile)) }] - else []) - + ( - if isSwApmEnabled then - [ - { - name: 'JAVA_TOOL_OPTIONS', - value: '-javaagent:/skywalking/agent/skywalking-agent.jar', - }, - { - name: 'SW_AGENT_COLLECTOR_BACKEND_SERVICES', - value: vars.swBackend + ':' + vars.swPort, - }, - { - name: 'SW_AGENT_NAMESPACE', - value: deployment_manifest.deployment.namespace, - }, - { - name: 'SW_AGENT_NAME', - value: deployment.name, - }, - { - name: 'SW_LOGGING_OUTPUT', - value: 'CONSOLE', - }, - { - name: 'ELASTIC_APM_ENABLED', - value: 'false', - }, - { - name: 'ELASTIC_APM_ACTIVE', - value: 'false', - }, - ] else [] - ), - image: image, //Directly passed to jssonnet via --ext-str command - imagePullPolicy: deployment.imagePullPolicy, - lifecycle: { - preStop: { - exec: { - command: ['sleep', if deployment_manifest.environment == 'prod' then std.toString - (0.8 * $.spec.terminationGracePeriodSeconds) else std.toString(0.5 * $.spec.terminationGracePeriodSeconds)], - }, - }, - }, - resources: { - limits: { - memory: if deployment.isVpaEnabled then deployment.instance.minMemory else deployment.instance.memory, - cpu: ( - if deployment.isVpaEnabled then - (if environment == environments.prod then deployment.instance.minCPU * 1.75 else deployment.instance.minCPU * 1.5) - else deployment.instance.cpu - ), - } + (if isGPUEnabled then { 'nvidia.com/gpu': deployment.instance.gpu } else {}), - requests: { - memory: if deployment.isVpaEnabled then deployment.instance.minMemory else deployment.instance.memory, - cpu: if deployment.isVpaEnabled then deployment.instance.minCPU else deployment.instance.cpu, - } + (if isGPUEnabled then { 'nvidia.com/gpu': deployment.instance.gpu } else {}), - }, - name: chart.full_service_name(deployment.name), - ports: port_map.getContainerPorts, - volumeMounts: - (if (isFsxNeeded) then - std.map(function(fsx) { - name: fsx.name, - mountPath: fsx.mountPath, - }, deployment.fsx) - else []) + - (if (isEfsNeeded) then - std.map(function(efs) { - name: efs.name, - mountPath: efs.mountPath, - }, deployment.efs) - else []) + - (if needsAWSAccess && namespace_values.zalandoEnabled then - [{ - name: 'aws-iam-credentials', - mountPath: '/meta/aws-iam', - readOnly: true, - }] else []) + - (if hasEnvironmentFile then - [{ - mountPath: util.parent_dir(deployment.environmentFile.path), - name: 'environment-file-volume', - }] else []) + - (if manifest_util.is_dynamic_config_present(deployment_manifest) then - [{ - mountPath: '/var/navi-app/dynamic_configuration', - name: 'dynamic-config-volume', - }] else []) + - (if heapDumpEnabled then - [{ - mountPath: '/dumps', - name: 'heap-dumps', - }] else []) + - (if isSwApmEnabled then - [{ - name: 'skywalking-agent', - mountPath: '/skywalking', - }] else []) + - [{ - mountPath: secret.path, - name: secret.name, - } for secret in deployment.mountSecrets], - [if util.is_readiness_probe_enabled(deployment.image, environment) then 'readinessProbe']: health_check_values.generator(readinessCheck)[readinessCheck.type], - [if util.is_liveness_probe_enabled(deployment.image, environment) then 'livenessProbe']: health_check_values.generator(livenessCheck)[livenessCheck.type], - [if util.is_startup_probe_enabled(deployment.healthChecks.startupProbeEnabled, deployment.image, environment) then 'startupProbe']: health_check_values.generator(startupProbe)[startupProbe.type], - }, - ], - terminationGracePeriodSeconds: deployment.terminationGracePeriodSeconds, - dnsConfig: { - options: [ - { - name: 'ndots', - value: '2', - }, - ], - }, - volumes: - (if (isFsxNeeded) then - std.map(function(fsx) { - name: fsx.name, - persistentVolumeClaim: { - claimName: fsx.name, - }, - }, deployment.fsx) - else []) + - (if (isEfsNeeded) then - std.map(function(efs) { - name: efs.name, - persistentVolumeClaim: { - claimName: chart.full_service_name(deployment.name) + '-' + efs.name, - }, - }, deployment.efs) - else []) + - (if hasEnvironmentFile then - [{ - configMap: { - name: chart.full_service_name(deployment.name) + '-cm', - }, - name: 'environment-file-volume', - }] else []) + - (if manifest_util.is_dynamic_config_present(deployment_manifest) then - [{ - name: 'dynamic-config-volume', - secret: { - secretName: chart.full_service_name(deployment_manifest.deployment.name) + '-dynamic-secret', - }, - }] else []) + - (if needsAWSAccess && namespace_values.zalandoEnabled then - [{ - name: 'aws-iam-credentials', - secret: { - secretName: roleName, - }, - }] else []) + - (if heapDumpEnabled then - [{ - name: 'heap-dumps', - emptyDir: {}, - }] else []) + - (if heapDumpEnabled then - [{ - name: 'aws-iam-credentials-heap-dump', - secret: { - secretName: 'java-heap-dump-bucket-role', - }, - }] else []) + - (if isSwApmEnabled then - [{ - name: 'skywalking-agent', - emptyDir: {}, - }] else []) + - [{ name: secret.name, secret: { secretName: secret.name } } for secret in deployment.mountSecrets], - } + (if (needsAWSAccess && !namespace_values.zalandoEnabled) then { serviceAccountName: roleName } else {}), -} diff --git a/templates/port_map.jsonnet b/templates/port_map.jsonnet deleted file mode 100644 index a502209e..00000000 --- a/templates/port_map.jsonnet +++ /dev/null @@ -1,50 +0,0 @@ -local chart = import 'chart.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local exposedPorts = if std.objectHas(deployment_manifest, 'flink') then - [{ name: chart.full_service_name(deployment_manifest.name) + '-rest', port: 'rest' }] -else - deployment_manifest.deployment.exposedPorts; - -{ - hasPort(ports, portName):: if portName in self.parsePorts(ports) then true else false, - parsePorts(ports):: { - [port.name]: port.port - for port in ports - }, - getServicePorts:: [ - { - name: port.name, - port: port.port, - protocol: 'TCP', - targetPort: port.port, - } - for port in exposedPorts - ], - getPortsforClusterIPService:: [ - { - name: port.name, - port: port.port, - protocol: 'TCP', - nodePort: null, - targetPort: port.port, - } - for port in exposedPorts - ], - getContainerPorts:: [ - { - containerPort: port.port, - protocol: 'TCP', - } - for port in exposedPorts - ], - getPort(portName):: if portName in self.parsePorts(exposedPorts) then self.parsePorts(exposedPorts)[portName] else null, - isGrpcEnabled(name):: ( - local result = std.filter(function(obj) obj.name == name, exposedPorts); - if std.length(result) == 0 then - false - else if 'enableGrpc' in result[0] then - result[0].enableGrpc - else - false - ), -} diff --git a/templates/rollout.jsonnet b/templates/rollout.jsonnet deleted file mode 100644 index 47ff281f..00000000 --- a/templates/rollout.jsonnet +++ /dev/null @@ -1,31 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment_util = import 'deployment_util.jsonnet'; -local pod_template = import 'pod_template.jsonnet'; -local deployment = deployment_manifest.deployment; -local vars = import 'vars.jsonnet'; -local strategyConfig = deployment.strategy.config; - -if (deployment.controller == vars.rolloutController) then { - apiVersion: 'argoproj.io/v1alpha1', - kind: 'Rollout', - metadata: { - name: chart.full_service_name(deployment.name), - labels: common.labels { - linkConfig: std.toString(deployment_manifest.deployment.isLinkConfig), - }, - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations, - }, - spec: { - progressDeadlineSeconds: deployment.progressDeadlineSeconds, - selector: { - matchLabels: common.matchLabels, - }, - template: pod_template, - strategy: if deployment.strategy == 'canary' then deployment_util.strategy.canary(if 'canaryConfig' in deployment.strategyConfig then deployment.strategyConfig.canaryConfig else {}) - else if deployment.strategy == 'rollingUpdateWithCanaryMixIn' then deployment_util.strategy.rollingUpdateWithCanaryMixIn(deployment.strategyConfig.rollingUpdateWithCanaryMixInConfig) - else deployment_util.strategy.rollingUpdate(), - }, -} diff --git a/templates/rollout_analysis_template.jsonnet b/templates/rollout_analysis_template.jsonnet deleted file mode 100644 index 8519c12c..00000000 --- a/templates/rollout_analysis_template.jsonnet +++ /dev/null @@ -1,33 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local vars = import 'vars.jsonnet'; -local templateEnabled = if 'analysisTemplate' in deployment.strategyConfig then true else false; - -if (deployment.controller == vars.rolloutController && templateEnabled) then { - apiVersion: 'argoproj.io/v1alpha1', - kind: 'AnalysisTemplate', - metadata: { - name: chart.full_service_name(deployment.name), - labels: common.labels, - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations, - }, - spec: { - metrics: [ - { - name: 'degrade-rollout', - interval: deployment.strategyConfig.analysisTemplate.interval, - successCondition: 'result' + deployment.strategyConfig.analysisTemplate.operator + deployment.strategyConfig.analysisTemplate.threshold, - failureLimit: deployment.strategyConfig.analysisTemplate.failureLimit, - provider: { - prometheus: { - address: 'http://prometheus-kube-prometheus.monitoring.svc.cluster.local:9090', - query: deployment.strategyConfig.analysisTemplate.query, - }, - }, - }, - ], - }, -} diff --git a/templates/sandbox/access_role.jsonnet b/templates/sandbox/access_role.jsonnet deleted file mode 100644 index ad929e2f..00000000 --- a/templates/sandbox/access_role.jsonnet +++ /dev/null @@ -1,80 +0,0 @@ -local common = import '../common.jsonnet'; -local deployment_manifest = import '../deployment_manifest.jsonnet'; -local namespace = deployment_manifest.deployment.namespace; - -{ - apiVersion: 'rbac.authorization.k8s.io/v1', - kind: 'Role', - metadata: { - name: namespace + '-full-access', - namespace: namespace, - labels: common.labels - }, - rules: [ - { - apiGroups: [""], - resources: [ - "configmaps", - "endpoints", - "persistentvolumeclaims", - "pods", - "replicationcontrollers", - "replicationcontrollers/scale", - "serviceaccounts", - "services", - "events", - "limitranges", - "pods/log", - "pods/status", - "replicationcontrollers/status", - "resourcequotas", - "resourcequotas/status", - ], - verbs: ["get", "list", "watch"], - }, - { - apiGroups: ["apps"], - resources: [ - "controllerrevisions", - "daemonsets", - "deployments", - "deployments/scale", - "replicasets", - "replicasets/scale", - "statefulsets", - "statefulsets/scale", - ], - verbs: ["get", "list", "watch"], - }, - { - apiGroups: ["autoscaling"], - resources: ["horizontalpodautoscalers"], - verbs: ["get", "list", "watch"], - }, - { - apiGroups: ["batch"], - resources: ["cronjobs", "jobs"], - verbs: ["get", "list", "watch"], - }, - { - apiGroups: ["policy"], - resources: ["poddisruptionbudgets"], - verbs: ["get", "list", "watch"], - }, - { - apiGroups: ["networking.k8s.io"], - resources: ["ingresses", "networkpolicies"], - verbs: ["get", "list", "watch"], - }, - { - apiGroups: [""], - resources: ["configmaps", "pods/portforward", "pods/exec"], - verbs: ["get", "update", "create"], - }, - { - apiGroups: ["apps"], - resources: ["deployments"], - verbs: ["create", "update", "patch", "delete"], - }, - ], -} \ No newline at end of file diff --git a/templates/sandbox/access_role_binding.jsonnet b/templates/sandbox/access_role_binding.jsonnet deleted file mode 100644 index 0a9e7887..00000000 --- a/templates/sandbox/access_role_binding.jsonnet +++ /dev/null @@ -1,26 +0,0 @@ -local common = import '../common.jsonnet'; -local deployment_manifest = import '../deployment_manifest.jsonnet'; -local sandboxParams = deployment_manifest.sandboxParams; -local namespace = deployment_manifest.deployment.namespace; - -{ - apiVersion: 'rbac.authorization.k8s.io/v1', - kind: 'RoleBinding', - metadata: { - name: namespace + "-full-access", - namespace: namespace, - labels: common.labels - }, - roleRef: { - apiGroup: 'rbac.authorization.k8s.io', - kind: 'Role', - name: namespace + '-full-access', - }, - subjects: [ - { - apiGroup: "rbac.authorization.k8s.io", - kind: "User", - name: "remote-"+sandboxParams.email+"-teleport.cmd.navi-tech.in" - } - ] -} \ No newline at end of file diff --git a/templates/sandbox/aws_iam_role.jsonnet b/templates/sandbox/aws_iam_role.jsonnet deleted file mode 100644 index e8ed2973..00000000 --- a/templates/sandbox/aws_iam_role.jsonnet +++ /dev/null @@ -1,36 +0,0 @@ -local chart = import '../chart.jsonnet'; -local common = import '../common.jsonnet'; -local deployment_manifest = import '../deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local sourceEnvironment = deployment_manifest.sandboxParams.source.environment; -local environment = deployment_manifest.environment; -local full_name = chart.full_service_name(deployment.name); -local namespace_values = import '../namespace_values.jsonnet'; - -if (deployment_manifest.extraResources != null - && 'aws_access' in deployment_manifest.extraResources) then - if (namespace_values.zalandoEnabled) then { - apiVersion: 'zalando.org/v1', - kind: 'AWSIAMRole', - metadata: { - name: '%s-%s' % [full_name, environment], - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations, - }, - spec: { - roleReference: '%s-%s' % [full_name, sourceEnvironment], - }, - } else { - apiVersion: 'v1', - kind: 'ServiceAccount', - metadata: { - annotations: { - 'eks.amazonaws.com/role-arn': 'arn:aws:iam::%s:role/%s-%s' % [namespace_values.awsAccountId, full_name, sourceEnvironment], - 'eks.amazonaws.com/sts-regional-endpoints': 'true', - 'eks.amazonaws.com/token-expiration': '10800', - }, - name: '%s-%s' % [full_name, environment], - namespace: deployment_manifest.deployment.namespace, - }, - } -else null diff --git a/templates/sandbox/main.jsonnet b/templates/sandbox/main.jsonnet deleted file mode 100644 index a52f1b1d..00000000 --- a/templates/sandbox/main.jsonnet +++ /dev/null @@ -1,53 +0,0 @@ -local namespace = import "namespace.jsonnet"; -local roleBinding = import "role_binding.jsonnet"; -local accessRole = import "access_role.jsonnet"; -local accessRoleBinding = import "access_role_binding.jsonnet"; -local deployment_manifest = import '../deployment_manifest.jsonnet'; -local namespace = import 'namespace.jsonnet'; -local sandboxParams = deployment_manifest.sandboxParams; -local roleBinding = import 'role_binding.jsonnet'; -local groupOrder = '20'; -local awsIamRole = import 'aws_iam_role.jsonnet'; -{ - sandbox: function(config={}) { - local _config = { - routingKey: if sandboxParams != null then sandboxParams.routingKey, - serviceName: null, - servicePort: null, - } + config, - namespace: namespace, - roleBinding: roleBinding, - securityContext: { - runAsUser: 0, - }, - albIngress: { - annotations: { - assert _config.serviceName != null : 'serviceName is required', - assert _config.servicePort != null : 'servicePort is required', - assert _config.routingKey != null : 'routingKey is required', - 'alb.ingress.kubernetes.io/actions.sandbox': '{"Type":"forward","ForwardConfig":{"TargetGroups":[{"ServiceName":"%s","ServicePort":"%s","Weight":100}]}}' % [_config.serviceName, _config.servicePort], - 'alb.ingress.kubernetes.io/conditions.sandbox': '[{"field":"http-header","httpHeaderConfig":{"httpHeaderName": "routing_key", "values":["%s"]}}]' % _config.routingKey, - 'alb.ingress.kubernetes.io/group.order': groupOrder, - }, - host: { - paths: [ - { - pathType: 'ImplementationSpecific', - backend: { - service: { - name: 'sandbox', - port: { - name: 'use-annotation', - }, - }, - }, - }, - ], - }, - }, - rolebinding: roleBinding, - accessRoleBinding: accessRoleBinding, - accessRole: accessRole, - iamRole: awsIamRole - }, -} \ No newline at end of file diff --git a/templates/sandbox/namespace.jsonnet b/templates/sandbox/namespace.jsonnet deleted file mode 100644 index bbcbb52f..00000000 --- a/templates/sandbox/namespace.jsonnet +++ /dev/null @@ -1,17 +0,0 @@ -local common = import '../common.jsonnet'; -local deployment_manifest = import '../deployment_manifest.jsonnet'; -local namespace = deployment_manifest.deployment.namespace; - -local metadata = { - labels: { - privilege: 'true', - prometheus: 'kube-prometheus', - }, - name: namespace, -}; - -{ - apiVersion: 'v1', - kind: 'Namespace', - metadata: metadata, -} diff --git a/templates/sandbox/role_binding.jsonnet b/templates/sandbox/role_binding.jsonnet deleted file mode 100644 index 76232fa6..00000000 --- a/templates/sandbox/role_binding.jsonnet +++ /dev/null @@ -1,25 +0,0 @@ -local common = import '../common.jsonnet'; -local deployment_manifest = import '../deployment_manifest.jsonnet'; -local namespace = deployment_manifest.deployment.namespace; - -{ - apiVersion: 'rbac.authorization.k8s.io/v1', - kind: 'RoleBinding', - metadata: { - name: 'psp:privileged:' + namespace, - labels: common.labels, - namespace: namespace, - }, - roleRef: { - apiGroup: 'rbac.authorization.k8s.io', - kind: 'ClusterRole', - name: 'psp:privileged', - }, - subjects: [ - { - apiGroup: 'rbac.authorization.k8s.io', - kind: 'Group', - name: 'system:serviceaccounts:' + namespace, - }, - ], -} diff --git a/templates/secret.jsonnet b/templates/secret.jsonnet deleted file mode 100644 index d400d9b2..00000000 --- a/templates/secret.jsonnet +++ /dev/null @@ -1,18 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local namespace = if 'flink' in deployment_manifest then deployment_manifest.flink.namespace else deployment_manifest.deployment.namespace; - -{ - apiVersion: 'v1', - kind: 'Secret', - metadata: { - name: chart.full_service_name(deployment_manifest.name) + '-secret', - labels: common.labels, - namespace: namespace, - annotations: common.annotations, - }, - - data: { [e.name]: std.base64(e.value) for e in deployment_manifest.environmentVariables }, - type: 'Opaque', -} diff --git a/templates/security_group.jsonnet b/templates/security_group.jsonnet deleted file mode 100644 index 337c0023..00000000 --- a/templates/security_group.jsonnet +++ /dev/null @@ -1,32 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -if 'securityGroup' in deployment then - local security_group = deployment.securityGroup; - [{ - apiVersion: 'aws.navi.com/v1', - kind: 'SecurityGroup', - metadata: { - name: '%s-%s' % [chart.full_service_name(deployment_manifest.deployment.name), sg.name], - labels: common.labels, - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations, - }, - spec: { - rules: [ - { - local ipv4_cidrs = [cidr for cidr in rule.ingressCidr if std.findSubstr(':',cidr) == []], - local ipv6_cidrs = [cidr for cidr in rule.ingressCidr if std.findSubstr(':',cidr) != []], - [if 'fromPort' in rule then 'fromPort']: rule.fromPort, - [if 'toPort' in rule then 'toPort']: rule.toPort, - [if 'protocol' in rule then 'protocol']: rule.protocol, - [if 'description' in rule then 'description']: rule.description, - [if 'ingressCidr' in rule then 'ingressCidr']: ipv4_cidrs, - [if 'ingressCidr' in rule then 'ipv6ingressCidr']: ipv6_cidrs, - } - for rule in sg.rules - ], - [if 'vpcId' in sg then 'vpcId']: sg.vpcId, - }, - } for sg in security_group] diff --git a/templates/service.jsonnet b/templates/service.jsonnet deleted file mode 100644 index 79af347d..00000000 --- a/templates/service.jsonnet +++ /dev/null @@ -1,119 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local health_check_values = import 'health_check_values.jsonnet'; -local load_balancer_util = import 'load_balancer_util.jsonnet'; -local namespace_values = import 'namespace_values.jsonnet'; -local port_map = import 'port_map.jsonnet'; -local util = import 'util.jsonnet'; -local vars = import 'vars.jsonnet'; -local deployment = deployment_manifest.deployment; -local livenessCheck = deployment.healthChecks.livenessCheck; - -local elbScheme = { - internetFacing: 'false', - internal: 'true', -}; - -local name = chart.full_service_name(deployment.name); -local services = [name] + if (deployment.controller == vars.rolloutController) then ['%s-canary' % name, '%s-stable' % name] else []; - -local albTags = common.awsTags; - -local load_balancer_spec = { - alb: { - type: 'ClusterIP', - ports: port_map.getServicePorts, - }, - //If shared Alb is used all accessPolicies are ignored for now - sharedAlbAcrossNamespace: self.alb, - nodePort: self.alb, - commonApiGateway: self.alb, - - elb: { - type: 'LoadBalancer', - loadBalancerSourceRanges: namespace_values.loadBalancer.sourceRanges, - ports: [{ - port: 443, - targetPort: port_map.getPort('serviceport'), - protocol: 'TCP', - name: 'https', - }] + port_map.getServicePorts, - }, - - // If elb or alb is being created, a clusterIP is created by default - kubeLb: { - type: 'ClusterIP', - ports: port_map.getServicePorts, - }, - - nginxLb: self.kubeLb, - - // Creates a kubernetes headless service - none: { - type: 'ClusterIP', - ports: port_map.getServicePorts, - }, -}; - -local lb_annotations_mixin(albTags) = - local elbObjects = std.filter(function(lbObject) lbObject.type == 'elb', deployment.loadBalancers); - - // Only first elb loadbalancer configuration is considered - local elb_annotations_mixin = - if elbObjects != [] then - { - 'service.beta.kubernetes.io/aws-load-balancer-ssl-ports': 'https', - 'service.beta.kubernetes.io/aws-load-balancer-backend-protocol': 'http', - 'service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout': '3600', - 'service.beta.kubernetes.io/aws-load-balancer-extra-security-groups': - load_balancer_util.security_group_list(elbObjects[0].accessPolicies, super.securityGroups, elbObjects[0].extraSecurityGroups), - 'service.beta.kubernetes.io/aws-load-balancer-ssl-cert': super.sslCert[util.get_certs(std - .objectFieldsAll(super.sslCert), elbObjects[0].endpoint)], - 'service.beta.kubernetes.io/aws-load-balancer-internal': elbScheme[load_balancer_util.subnet_scheme(elbObjects[0].accessPolicies)], - 'external-dns.alpha.kubernetes.io/hostname': elbObjects[0].endpoint, - 'external-dns.alpha.kubernetes.io/ttl': '60', - } - else {}; - - local albObjects = std.filter(function(lbObject) std.prune([std.find(loadBalancers.type, ['alb', 'sharedAlbAcrossNamespace']) for loadBalancers in deployment.loadBalancers]) != [], deployment.loadBalancers); - - // Only first alb/sharedAlbAcrossNamespace loadbalancer configuration is considered - local alb_annotations_mixin = - if albObjects != [] then - { - 'alb.ingress.kubernetes.io/healthcheck-path': livenessCheck.path, - 'alb.ingress.kubernetes.io/healthcheck-port': std.toString(port_map.getPort(livenessCheck.port)), - 'alb.ingress.kubernetes.io/tags': 'Environment=%(Environment)s,Owner=%(Owner)s,Name=%(Name)s,Team=%(Team)s,Namespace=%(Namespace)s' % (albTags), - } - else {}; - - elb_annotations_mixin + alb_annotations_mixin; - - -//Kubernetes Service Object - -local create_service(name) = { - local tags = albTags { Name: name }, - apiVersion: 'v1', - kind: 'Service', - metadata: { - labels: common.labels, - name: name, - annotations: common.annotations + namespace_values.loadBalancer.annotations + lb_annotations_mixin(tags), - namespace: deployment_manifest.deployment.namespace, - }, - - spec: { - selector: { - app: chart.service_name, - release: deployment.name, - }, - } + load_balancer_spec[deployment.loadBalancers[0].type], -}; -// this if condition is only added so older test get passed. we need to update older tests fixture and than remove this -if (std.length(services) == 1) then create_service(name) else { - apiVersion: 'v1', - kind: 'List', - items: [create_service(service) for service in services], -} diff --git a/templates/service_monitor.jsonnet b/templates/service_monitor.jsonnet deleted file mode 100644 index 95462ea1..00000000 --- a/templates/service_monitor.jsonnet +++ /dev/null @@ -1,37 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; - -if deployment_manifest.deployment.serviceMonitor.enabled == true then { - apiVersion: 'monitoring.coreos.com/v1', - kind: 'ServiceMonitor', - metadata: { - labels: common.labels, - name: chart.full_service_name(deployment_manifest.deployment.name) + '-monitor', - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations, - }, - spec: - { - endpoints: [ - { - honorLabels: false, - interval: deployment_manifest.deployment.serviceMonitor.interval, - path: deployment_manifest.deployment.serviceMonitor.path, - port: deployment_manifest.deployment.serviceMonitor.port, - metricRelabelings: deployment_manifest.deployment.serviceMonitor.metricRelabelings, - scrapeTimeout: deployment_manifest.deployment.serviceMonitor.scrapeTimeout, - }, - ], - namespaceSelector: { - matchNames: [ - deployment_manifest.deployment.namespace, - ], - }, - //adding hard limit on scrape sample per target - sampleLimit: 20000, - selector: { - matchLabels: common.matchLabels, - }, - }, -} diff --git a/templates/shared_ingress_config/main.jsonnet b/templates/shared_ingress_config/main.jsonnet deleted file mode 100644 index 51da141f..00000000 --- a/templates/shared_ingress_config/main.jsonnet +++ /dev/null @@ -1,5 +0,0 @@ -local shared_ingress = import 'shared_ingress.libsonnet'; - -function(cluster, namespace, group_name, environment, product="shared") { - '10_ingress.json': shared_ingress.create(cluster, namespace, group_name, environment, product) -} diff --git a/templates/shared_ingress_config/shared_ingress.libsonnet b/templates/shared_ingress_config/shared_ingress.libsonnet deleted file mode 100644 index db88eb0e..00000000 --- a/templates/shared_ingress_config/shared_ingress.libsonnet +++ /dev/null @@ -1,75 +0,0 @@ -local cluster_values = import '../cluster_values.jsonnet'; - -local defaults = { - idle_timeout_seconds: 60, - access_logs_enable: true, - ssl_policy: 'ELBSecurityPolicy-TLS-1-2-2017-01', - team_name: 'Shared', - labels: { - product: 'shared', - owner: 'shared', - heritage: 'NaviDeploymentManifest', - }, -}; - -{ - namespace_values(cluster, namespace):: - local cluster_value = cluster_values[cluster]; - if namespace in cluster_value - then cluster_value[namespace] - else cluster_value.default, - - annotations(cluster, namespace, group_name, environment, product):: - local namespace_values = $.namespace_values(cluster, namespace); - local cluster_annotations = namespace_values.loadBalancer.annotations; - local security_groups = cluster_annotations.securityGroups; - local ingress_sg = std.join(',', [security_groups.officeIp, security_groups.internal]); - local loadbalancer_attributes = std.join(',', [ - 'idle_timeout.timeout_seconds=%s' % defaults.idle_timeout_seconds, - 'access_logs.s3.enabled=%s' % defaults.access_logs_enable, - 'access_logs.s3.bucket=%s' % cluster_annotations.accessLogBucket, - 'access_logs.s3.prefix=%s' % group_name, - ]); - - { - 'alb.ingress.kubernetes.io/ssl-policy': defaults.ssl_policy, - 'alb.ingress.kubernetes.io/scheme': 'internal', - 'alb.ingress.kubernetes.io/security-groups': ingress_sg, - 'alb.ingress.kubernetes.io/load-balancer-attributes': loadbalancer_attributes, - [if cluster != 'spike.np.navi-tech.in' then 'alb.ingress.kubernetes.io/subnets']: cluster_annotations.subnets.internal, - 'alb.ingress.kubernetes.io/group.name': group_name, - 'alb.ingress.kubernetes.io/tags': 'Name=shared-alb-%(name)s,Ingress=shared-alb-%(name)s,Owner=shared,Team=Shared,Product=%(product)s,Environment=%(environment)s' % { name: group_name, product: product, environment: environment }, - 'kubernetes.io/ingress.class': 'alb', - }, - - labels(name, environment, product):: - { - app: name, - chart: name, - heritage: defaults.labels.heritage, - release: name, - Team: defaults.team_name, - Environment: environment, - Name: name, - Product: product, - Owner: defaults.labels.owner, - }, - - name(group_name):: '%s-shared-alb-config' % [group_name], - - create(cluster, namespace, group_name, environment, product=defaults.labels.product):: - local name = $.name(group_name); - { - apiVersion: 'networking.k8s.io/v1', - kind: 'Ingress', - metadata: { - name: name, - labels: $.labels(name, environment, product), - namespace: namespace, - annotations: $.annotations(cluster, namespace, group_name, environment, product), - }, - spec: { - rules: [{}], - }, - }, -} diff --git a/templates/shared_ingress_config/tests/expected/ingress/nonprod.np.navi-tech.in:dev-internal:custom-group-name:dev.json b/templates/shared_ingress_config/tests/expected/ingress/nonprod.np.navi-tech.in:dev-internal:custom-group-name:dev.json deleted file mode 100644 index 435667f4..00000000 --- a/templates/shared_ingress_config/tests/expected/ingress/nonprod.np.navi-tech.in:dev-internal:custom-group-name:dev.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "apiVersion": "networking.k8s.io/v1", - "kind": "Ingress", - "metadata": { - "annotations": { - "alb.ingress.kubernetes.io/group.name": "custom-group-name", - "alb.ingress.kubernetes.io/load-balancer-attributes": "idle_timeout.timeout_seconds=60,access_logs.s3.enabled=true,access_logs.s3.bucket=navi-nonprod-lb-access-logs,access_logs.s3.prefix=custom-group-name", - "alb.ingress.kubernetes.io/scheme": "internal", - "alb.ingress.kubernetes.io/security-groups": "sg-01a64c085bfdb2cbb,sg-0bc07e856d000a5f4", - "alb.ingress.kubernetes.io/ssl-policy": "ELBSecurityPolicy-TLS-1-2-2017-01", - "alb.ingress.kubernetes.io/subnets": "internal-lb-ap-south-1a.nonprod.np.navi-tech.in,internal-lb-ap-south-1b.nonprod.np.navi-tech.in", - "alb.ingress.kubernetes.io/tags": "Name=shared-alb-custom-group-name,Ingress=shared-alb-custom-group-name,Owner=shared,Team=Shared,Product=shared,Environment=dev", - "kubernetes.io/ingress.class": "alb" - }, - "labels": { - "Environment": "dev", - "Name": "custom-group-name-shared-alb-config", - "Owner": "shared", - "Product": "shared", - "Team": "Shared", - "app": "custom-group-name-shared-alb-config", - "chart": "custom-group-name-shared-alb-config", - "heritage": "NaviDeploymentManifest", - "release": "custom-group-name-shared-alb-config" - }, - "name": "custom-group-name-shared-alb-config", - "namespace": "dev-internal" - }, - "spec": { - "rules": [ - {} - ] - } -} diff --git a/templates/shared_ingress_config/tests/jsonnetfile.json b/templates/shared_ingress_config/tests/jsonnetfile.json deleted file mode 100644 index 65c2176d..00000000 --- a/templates/shared_ingress_config/tests/jsonnetfile.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "version": 1, - "dependencies": [ - { - "source": { - "git": { - "remote": "https://github.com/yugui/jsonnetunit.git", - "subdir": "jsonnetunit" - } - }, - "version": "master" - } - ], - "legacyImports": true -} diff --git a/templates/shared_ingress_config/tests/jsonnetfile.lock.json b/templates/shared_ingress_config/tests/jsonnetfile.lock.json deleted file mode 100644 index b2f6ed72..00000000 --- a/templates/shared_ingress_config/tests/jsonnetfile.lock.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "version": 1, - "dependencies": [ - { - "source": { - "git": { - "remote": "https://github.com/yugui/jsonnetunit.git", - "subdir": "jsonnetunit" - } - }, - "version": "6927c58cae7624a00f368b977ccc477d4f74071f", - "sum": "9FFqqln65hooRF0l6rjICDtnTxUlmDj34+sKMh4sjPI=" - } - ], - "legacyImports": false -} diff --git a/templates/shared_ingress_config/tests/shared_ingress.jsonnet b/templates/shared_ingress_config/tests/shared_ingress.jsonnet deleted file mode 100644 index 232f43af..00000000 --- a/templates/shared_ingress_config/tests/shared_ingress.jsonnet +++ /dev/null @@ -1,49 +0,0 @@ -local shared_ingress = import '../shared_ingress.libsonnet'; -local test = import './vendor/jsonnetunit/test.libsonnet'; - -test.suite({ - testName: { - actual: shared_ingress.name('group-name'), - expect: 'group-name-shared-alb-config', - }, - testAnnotations: { - actual: shared_ingress.annotations('nonprod.np.navi-tech.in', 'dev', 'group_name', 'dev', product='shared'), - expect: { - 'alb.ingress.kubernetes.io/group.name': 'group_name', - 'alb.ingress.kubernetes.io/load-balancer-attributes': 'idle_timeout.timeout_seconds=60,access_logs.s3.enabled=true,access_logs.s3.bucket=navi-nonprod-lb-access-logs,access_logs.s3.prefix=group_name', - 'alb.ingress.kubernetes.io/scheme': 'internal', - 'alb.ingress.kubernetes.io/security-groups': 'sg-01a64c085bfdb2cbb,sg-0bc07e856d000a5f4', - 'alb.ingress.kubernetes.io/ssl-policy': 'ELBSecurityPolicy-TLS-1-2-2017-01', - 'alb.ingress.kubernetes.io/subnets': 'internal-lb-ap-south-1a.nonprod.np.navi-tech.in,internal-lb-ap-south-1b.nonprod.np.navi-tech.in', - 'alb.ingress.kubernetes.io/tags': 'Name=shared-alb-group_name,Ingress=shared-alb-group_name,Owner=shared,Team=Shared,Product=shared,Environment=dev', - 'kubernetes.io/ingress.class': 'alb', - }, - }, - testLabels: { - local name = 'group-name-shared-alb-config', - local env = 'dev', - local product = 'shared', - - actual: shared_ingress.labels(name, env, product), - expect: { - app: name, - chart: name, - heritage: 'NaviDeploymentManifest', - release: name, - Team: 'Shared', - Environment: env, - Name: name, - Product: 'shared', - Owner: 'shared', - }, - }, - testIngress: { - local cluster = 'nonprod.np.navi-tech.in', - local namespace = 'dev-internal', - local environment = 'dev', - local group_name = 'custom-group-name', - - actual: shared_ingress.create(cluster, namespace, group_name, environment), - expect: import './expected/ingress/nonprod.np.navi-tech.in:dev-internal:custom-group-name:dev.json', - }, -}) diff --git a/templates/sidecar.jsonnet b/templates/sidecar.jsonnet deleted file mode 100644 index 00e9484c..00000000 --- a/templates/sidecar.jsonnet +++ /dev/null @@ -1,87 +0,0 @@ -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local deployment = deployment_manifest.deployment; -local namespace_values = import 'namespace_values.jsonnet'; -local vars = import 'vars.jsonnet'; -local util = import 'util.jsonnet'; -local cluster = deployment_manifest.cluster; -local namespace = deployment.namespace; - -local outboundTrafficPolicy = { - "nonprod.np.navi-tech.in": { - "dev": { mode: 'ALLOW_ANY' }, - "qa": { mode: 'ALLOW_ANY' }, - }, -}; - -local getOutboundTrafficPolicy(cluster, namespace) = ( - local envConf = util.get(outboundTrafficPolicy, cluster, {}); - local policy = util.get(envConf, namespace, {}); - policy -); - -// Istio sidecar need not be deployed for Infra team or applications in command cluster -if (deployment_manifest.team.name != 'Infra' && namespace_values.sidecarEnabled -&& !deployment.disableIstio) then { - local chart = import 'chart.jsonnet', - local common = import 'common.jsonnet', - local util = import 'util.jsonnet', - - local default_egress_list = [ - 'istio-system/*', - '*/' + vars.swBackend, - ], - - - // Applies namespace prefix as required by sidecar configuration - // FROM [ "dev-payment.np.navi-tech.in", - // "dev-camunda.np.navi-tech.in", - // "192.168.1.1", - // - // TO [ "*/dev-payment.np.navi-tech.in", - // "*/dev-camunda.np.navi-tech.in", - // "192.168.1.1" ] - local sidecar_egress_list(egressEndpoints) = - std.map(function(egressEndpoint) if util.is_ipv4_address(egressEndpoint) then egressEndpoint else '*/' + egressEndpoint, egressEndpoints), - - // Converts a array of endpoint urls to flat array of hostnames - // FROM [ "https://dev-payment.np.navi-tech.in", - // "https://dev-camunda.np.navi-tech.in", - // "192.168.1.1", - // "kafka-0.np.navi-tech.in:19092,kafka-1.np.navi-tech.in:19092,kafka-2.np.navi-tech.in:19092" ] - // - // TO [ "dev-payment.np.navi-tech.in", - // "dev-camunda.np.navi-tech.in", - // "192.168.1.1", - // "kafka-0.np.navi-tech.in", - // "kafka-1.np.navi-tech.in", - // "kafka-2.np.navi-tech.in" ] - local host_list(egressEndpoints) = - std.flattenArrays([ - if std.findSubstr(',', egressEndpoint) != [] then std.map(util.host_name, std.split(egressEndpoint, ',')) - else [util.host_name(egressEndpoint)] - for egressEndpoint in egressEndpoints - ]), - - apiVersion: 'networking.istio.io/v1alpha3', - kind: 'Sidecar', - metadata: { - name: chart.full_service_name(deployment.name) + '-sidecar', - labels: common.labels, - namespace: deployment.namespace, - annotations: common.annotations, - }, - spec: { - workloadSelector: { - labels: { - app: chart.service_name, - release: deployment.name, - }, - }, - outboundTrafficPolicy: getOutboundTrafficPolicy(cluster, namespace), - egress: [ - { - hosts: sidecar_egress_list(host_list(deployment.allowEgress)) + default_egress_list, - }, - ], - }, -} diff --git a/templates/util.jsonnet b/templates/util.jsonnet deleted file mode 100644 index de9ce6de..00000000 --- a/templates/util.jsonnet +++ /dev/null @@ -1,96 +0,0 @@ -local chart = import 'chart.jsonnet'; -local vars = import 'vars.jsonnet'; - -{ - parent_dir(filePath):: - std.splitLimit(filePath, '/', 1)[0], - - file_name(filePath):: - local words = std.split(filePath, '/'); - words[std.length(words) - 1], - - // Returns the root domain for given domain - // dev-camunda.np.navi-tech.in => navi-tech.in - // dev-camunda.np.navi-ext.com => navi-ext.com - root_domain(domain):: - local words = std.split(domain, '.'); - words[std.length(words) - 2] + '.' + words[std.length(words) - 1], - - get_certs(ssls, domain):: - local qualified_certificates = std.prune([if std.findSubstr(ssl, domain) != [] then ssl for ssl in std.sort(ssls)]); - if std.length(qualified_certificates) == 0 then error 'No cert found for domain: %s' % domain - else qualified_certificates[std.length(qualified_certificates) - 1], - - // Returns hostname for given full endpoint urls like following - // https://dev-camunda.np.navi-tech.in => dev-camuna.np.navi-tech.in - // https://dev-camunda.np.navi-tech.in/camunda => dev-camuna.np.navi-tech.in - // dev-camunda.np.navi-tech.in:3131 => dev-camuna.np.navi-tech.in - // 192.168.1.1 => 192.168.1.1 - host_name(endpoint):: - if std.findSubstr('://', endpoint) != [] then local hostNameStart = std.findSubstr('://', endpoint); self.host_name(std.substr(endpoint, hostNameStart[0] + 3, 9999)) - else if std.findSubstr(':', endpoint) != [] then self.host_name(std.split(endpoint, ':')[0]) - else if std.findSubstr('/', endpoint) != [] then self.host_name(std.split(endpoint, '/')[0]) - else endpoint, - - is_ipv4_address(endpoint):: - local ipChars = std.split(endpoint, '.'); - std.length(ipChars) == 4 && std.length(std.filter(function(ipChar) std.length(ipChar) >= 1 && std.length(ipChar) <= 3, ipChars)) == 4, - - is_field_present(object, field):: - if object == null then false - else std.objectHas(object, field), - - memory_in_mb(memory):: - local unitMap = { - Mi: 1, - Gi: 1024, - }; - local length = std.length(memory); - local value = std.parseInt(std.substr(memory, 0, length - 2)); - local unit = std.substr(memory, length - 2, 2); - value * unitMap[unit], - - cpu_in_milli_core(cpu):: - local cpuStr = cpu + ''; - if std.substr(cpuStr, std.length(cpuStr) - 1, 1) == 'm' then cpu else '%dm' % (cpu * 1000), - - replace_character_in_string(str, a, b):: ( - assert std.length(a) == 1; - std.join(b, std.split(str, a)) - ), - - is_sandbox(env):: if env == 'sandbox' then true else false, - - is_local_sandbox(image, env):: std.extVar('IMAGE') == 'null' && $.is_sandbox(env) && (image == null || image == 'null'), - - get_image(image, env):: - if std.extVar('IMAGE') == 'null' then - if $.is_local_sandbox(image, env) then - vars.sandboxImage - else - image - else - std.extVar('IMAGE'), - - is_readiness_probe_enabled(image, environment):: !$.is_local_sandbox(image, environment), - - is_liveness_probe_enabled(image, environment):: !$.is_local_sandbox(image, environment), - - is_startup_probe_enabled(is_enabled, image, environment):: is_enabled && !$.is_local_sandbox(image, environment), - - hpa_scale_target_ref(name, controller, isDisabled):: if isDisabled then { - apiVersion: 'apps/v1', - kind: 'Deployment', - name: 'disabled', - } else if (controller == vars.rolloutController) then { - apiVersion: 'argoproj.io/v1alpha1', - kind: 'Rollout', - name: chart.full_service_name(name), - } else { - apiVersion: 'apps/v1', - kind: 'Deployment', - name: chart.full_service_name(name), - }, - - get( object, key, defaultValue ):: if std.objectHas(object, key) then object[key] else defaultValue, -} diff --git a/templates/vars.jsonnet b/templates/vars.jsonnet deleted file mode 100644 index cf0ef47f..00000000 --- a/templates/vars.jsonnet +++ /dev/null @@ -1,44 +0,0 @@ -{ - esImage_7_17_0:: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/elastic-search:7.17.0-withplugins', - esImage_8_12_2:: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/elastic-search:8.12.2-withplugins', - kibanaImage_7_17_0:: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/kibana:7.17.0', - kibanaImage_8_12_2:: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/kibana:8.12.2', - sandboxImage:: '193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/busybox:navicli', - swBackend:: 'skywalking-skywalking-helm-oap.skywalking.svc.cluster.local', - swPort:: '11800', - rolloutController:: 'argo', - defaultController:: 'default', - defaultDeploymentStrategy:: 'rollingUpdate', - defaultCanarySteps: [ - { setWeight: 20 }, - { pause: {} }, - ], - environments: { - prod: 'prod', - dev: 'dev', - qa: 'qa', - perf: 'perf', - cmd: 'cmd', - }, - vpa:: { - maxAllowedCPU: '7200m', - maxAllowedMemory: '16Gi', - }, - deployment:: { - hpa:: { - type:: { - metrics:: 'metrics', - cron:: 'cron', - }, - }, - alerts:: { - pod:: [ - { type: 'HighPodRestarts', threshold: 3, duration: '30m', severity: 'critical' }, - { type: 'HighPodFailures', threshold: 2, duration: '3h', severity: 'warning' }, - { type: 'FrequentPodOOMKilled', threshold: 2, duration: '10m', severity: 'critical' }, - { type: 'PodOOMKilled', threshold: 1, duration: '5m', severity: 'warning' }, - { type: 'KubeContainerWaiting', threshold: 0, duration: '1h', severity: 'critical' }, - ], - }, - }, -} diff --git a/templates/vpa.jsonnet b/templates/vpa.jsonnet deleted file mode 100644 index 5630ec61..00000000 --- a/templates/vpa.jsonnet +++ /dev/null @@ -1,60 +0,0 @@ -local chart = import 'chart.jsonnet'; -local common = import 'common.jsonnet'; -local deployment_manifest = import 'deployment_manifest.jsonnet'; -local vars = import 'vars.jsonnet'; -local deployment = deployment_manifest.deployment; -local vpaEnabled = deployment.isVpaEnabled; -local namespace_values = import 'namespace_values.jsonnet'; -local util = import 'util.jsonnet'; - -local name = chart.full_service_name(deployment.name); -local vpaAllowed = namespace_values.isVpaDeployed; - -local minAllowed = { - cpu: util.cpu_in_milli_core(deployment.instance.minCPU), - memory: deployment.instance.minMemory, -}; - -local maxAllowed = { - cpu: util.cpu_in_milli_core(deployment.vpa.maxAllowed.cpu), - memory: deployment.vpa.maxAllowed.memory, -}; - -if vpaAllowed then { - apiVersion: 'autoscaling.k8s.io/v1', - kind: 'VerticalPodAutoscaler', - metadata: { - name: name, - labels: common.labels, - namespace: deployment_manifest.deployment.namespace, - annotations: common.annotations, - }, - spec: { - targetRef: if (deployment.controller == vars.rolloutController) then { - apiVersion: 'argoproj.io/v1alpha1', - kind: 'Rollout', - name: name, - } else { - apiVersion: 'apps/v1', - kind: 'Deployment', - name: name, - }, - [if !vpaEnabled then 'updatePolicy']: { - updateMode: 'Off', - }, - [if vpaEnabled then 'resourcePolicy']: { - containerPolicies: [ - { - containerName: name, - minAllowed: minAllowed, - maxAllowed: maxAllowed, - controlledResources: ['cpu', 'memory'], - }, - { - containerName: '*', - mode: 'Off', - }, - ], - }, - }, -} From 4593c6a419ee01fcdff9263b5b3d51ca92101b49 Mon Sep 17 00:00:00 2001 From: Ashvin Sharma Date: Fri, 5 Apr 2024 13:43:04 +0530 Subject: [PATCH 030/108] INFRA-809 | Ashvin | Disable CGO while building kutegen --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1602be51..3fc9454f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ WORKDIR /app COPY ./kutegen/go.mod ./kutegen/go.sum ./ RUN go mod download COPY ./kutegen ./ -RUN go build -o kutegen cmd/main.go +RUN CGO_ENABLED=0 go build -o kutegen cmd/main.go FROM ${BUILDER_CACHE_TARGET} as builder ARG ARTIFACT_VERSION=0.0.1-SNAPSHOT From 455df83ae4829db1fa515f7904531181a1bc8521 Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Fri, 5 Apr 2024 13:53:36 +0530 Subject: [PATCH 031/108] INFRA-809 | Ashvin | Disable CGO while building kutegen (#870) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1602be51..3fc9454f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ WORKDIR /app COPY ./kutegen/go.mod ./kutegen/go.sum ./ RUN go mod download COPY ./kutegen ./ -RUN go build -o kutegen cmd/main.go +RUN CGO_ENABLED=0 go build -o kutegen cmd/main.go FROM ${BUILDER_CACHE_TARGET} as builder ARG ARTIFACT_VERSION=0.0.1-SNAPSHOT From 8ecd222d842f821227e44874c597b4d12e6e203f Mon Sep 17 00:00:00 2001 From: Ashvin Sharma Date: Fri, 5 Apr 2024 15:11:11 +0530 Subject: [PATCH 032/108] INFRA-809 | Ashvin | Change the Alert.Threshold type to float64 Ctx: https://go-navi.slack.com/archives/C03B0RHGNBE/p1712309674980899 --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index b23e2ded..5f127fe3 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit b23e2dedf69914135c95dd8bab5537518aa3aba8 +Subproject commit 5f127fe31f98d837c81669d4566fbc515e7cfafe From 110c41c60d64350e972ce43881687ba24e7f28b2 Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Fri, 5 Apr 2024 15:24:53 +0530 Subject: [PATCH 033/108] INFRA-809 | Ashvin | Change the Alert.Threshold type to float64 (#871) * INFRA-809 | Ashvin | Disable CGO while building kutegen * INFRA-809 | Ashvin | Change the Alert.Threshold type to float64 Ctx: https://go-navi.slack.com/archives/C03B0RHGNBE/p1712309674980899 --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index b23e2ded..5f127fe3 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit b23e2dedf69914135c95dd8bab5537518aa3aba8 +Subproject commit 5f127fe31f98d837c81669d4566fbc515e7cfafe From 87ae93229c29b8601977e327971bf661ca23e182 Mon Sep 17 00:00:00 2001 From: Saurabh Bhagwan Sathe Date: Fri, 5 Apr 2024 16:05:59 +0530 Subject: [PATCH 034/108] INFRA-2972 | Saurabh | Json Schema Added (#868) --- .../extraResources/elasticCache.json | 81 ++++++++++++++++++- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/src/main/resources/jsonschema/extraResources/elasticCache.json b/src/main/resources/jsonschema/extraResources/elasticCache.json index 28a417e8..e1e9a6e9 100644 --- a/src/main/resources/jsonschema/extraResources/elasticCache.json +++ b/src/main/resources/jsonschema/extraResources/elasticCache.json @@ -1,12 +1,85 @@ + { "type": "object", - "required": [ - "instanceName" - ], + "required": ["instanceName", "elasticCacheAlertDurations", "elasticCacheAlertThresholds"], "properties": { "instanceName": { "type": "string", "pattern": "^(?!.*--)[a-zA-Z][a-zA-Z0-9-]{0,48}[a-zA-Z0-9]$" + }, + "elasticCacheAlertDurations": { + "type": "object", + "required": [ + "memoryUsage", + "cpuUtilization", + "cpuCreditBalance", + "networkBandwidthInAllowanceExceeded", + "networkBandwidthOutAllowanceExceeded", + "networkBandwidthTrackedAllowanceExceeded" + ], + "properties": { + "memoryUsage": { + "type": "integer", + "minimum": 0 + }, + "cpuUtilization": { + "type": "integer", + "minimum": 0 + }, + "cpuCreditBalance": { + "type": "integer", + "minimum": 0 + }, + "networkBandwidthInAllowanceExceeded": { + "type": "integer", + "minimum": 0 + }, + "networkBandwidthOutAllowanceExceeded": { + "type": "integer", + "minimum": 0 + }, + "networkBandwidthTrackedAllowanceExceeded": { + "type": "integer", + "minimum": 0 + } + } + }, + "elasticCacheAlertThresholds": { + "type": "object", + "required": [ + "memoryUsage", + "cpuUtilization", + "cpuCreditBalance", + "networkBandwidthInAllowanceExceeded", + "networkBandwidthOutAllowanceExceeded", + "networkBandwidthTrackedAllowanceExceeded" + ], + "properties": { + "memoryUsage": { + "type": "integer", + "minimum": 0 + }, + "cpuUtilization": { + "type": "integer", + "minimum": 0 + }, + "cpuCreditBalance": { + "type": "integer", + "minimum": 0 + }, + "networkBandwidthInAllowanceExceeded": { + "type": "integer", + "minimum": 0 + }, + "networkBandwidthOutAllowanceExceeded": { + "type": "integer", + "minimum": 0 + }, + "networkBandwidthTrackedAllowanceExceeded": { + "type": "integer", + "minimum": 0 + } + } } } -} \ No newline at end of file +} From 42bc0380f2706a556f3cb66787579b0985e6c84f Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 5 Apr 2024 18:18:50 +0530 Subject: [PATCH 035/108] INFRA-2219 | Harinder | Removing unused code in jitrequestrepository. Moving business logic of jit dag out of airflowclient. Updating SlackMessageElement's action_id to actionId for consistent format --- .../v2/client/airflow/AirflowClient.java | 22 +---------- .../jit/repository/JitRequestsRepository.java | 5 --- .../portal/v2/jit/service/JitServiceImpl.java | 39 ++++++++++++++++++- .../slackbotclient/SlackMessageElement.java | 6 ++- .../v2/jit/service/JitServiceImplTest.java | 9 ++--- 5 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java b/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java index 5b2cbd5e..272db6b9 100644 --- a/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java +++ b/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java @@ -94,28 +94,10 @@ public class AirflowClient { } public AirflowApiResponse triggerJitDag( - JitRequest jitRequest, String dagId, String runId, - String action + String payload ) { - LocalDateTime executionDate = action.equals("grant") ? jitRequest.getGrantAt() - : jitRequest.getGrantAt().plusHours(jitRequest.getGrantWindow()); - String apacheTimeFormat = String.join("+", - executionDate.toString(), "05:30"); - var payloadMap = Map.of("dag_run_id", runId, - "execution_date", apacheTimeFormat, - "conf", Map.of( - "vertical", jitRequest.getVertical().toString(), - "team", jitRequest.getTeam().getName(), - "env", jitRequest.getEnvironment().toString(), - "resource_type", jitRequest.getResourceType(), - "user", jitRequest.getRequestedFor().getEmail(), - "resource_action", jitRequest.getResourceAction(), - "action", action - )); - - var grantPayload = convertMapToString(payloadMap); try { var client = HttpClient.newHttpClient(); var request = HttpRequest.newBuilder() @@ -123,7 +105,7 @@ public class AirflowClient { .header("Cache-Control", "no-cache") .header("Content-Type", "application/json") .header("Authorization", "Basic " + this.authToken) - .POST(HttpRequest.BodyPublishers.ofString(grantPayload)) + .POST(HttpRequest.BodyPublishers.ofString(payload)) .build(); log.info("Triggering JIT DAG for runId: {}", runId); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java index 44c9c3c2..0953d36d 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java @@ -8,9 +8,4 @@ import org.springframework.stereotype.Repository; @Repository public interface JitRequestsRepository extends JpaRepository { - - @Modifying - @Query(value = "UPDATE jit_requests SET status = :action WHERE id = :jitId", - nativeQuery = true) - void updateRequestStatus(Long jitId, String action); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 1b133ac4..1d211219 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -1,5 +1,7 @@ package com.navi.infra.portal.v2.jit.service; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; import com.navi.infra.portal.v2.client.airflow.AirflowClient; @@ -24,6 +26,7 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; @@ -45,11 +48,13 @@ class JitServiceImpl implements JitService { private final AuthUtil authUtil; private final AirflowClient airflowClient; private final SlackBotClient slackBotClient; + private final ObjectMapper objectMapper; private final UserService userService; private final RoleService roleService; private final TeamService teamService; private final ResourceType resourceType = null; private final String env = null; + @Value("${jit.dag.id}") private String dagId; @@ -121,6 +126,34 @@ class JitServiceImpl implements JitService { : jitRequest.getGrantAt()); } + private String createAirflowDagPayload( + JitRequest jitRequest, + String runId, + String action + ) { + LocalDateTime executionDate = action.equals("grant") ? jitRequest.getGrantAt() + : jitRequest.getGrantAt().plusHours(jitRequest.getGrantWindow()); + String apacheTimeFormat = String.join("+", + executionDate.toString(), "05:30"); + var payloadMap = Map.of("dag_run_id", runId, + "execution_date", apacheTimeFormat, + "conf", Map.of( + "vertical", jitRequest.getVertical().toString(), + "team", jitRequest.getTeam().getName(), + "env", jitRequest.getEnvironment().toString(), + "resource_type", jitRequest.getResourceType(), + "user", jitRequest.getRequestedFor().getEmail(), + "resource_action", jitRequest.getResourceAction(), + "action", action + )); + + try { + return objectMapper.writeValueAsString(payloadMap); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + @Transactional private void processJitRequest( String reviewerEmail, @@ -189,8 +222,10 @@ class JitServiceImpl implements JitService { jitRequest.getRequestedFor().getEmail(), jitRequest.getResourceType(), jitRequest.getResourceAction()); validateGrantTime(jitRequest); - airflowClient.triggerJitDag(jitRequest, dagId, runId + "-grant", "grant"); - airflowClient.triggerJitDag(jitRequest, dagId, runId + "-revoke", "revoke"); + airflowClient.triggerJitDag(dagId, runId + "-revoke", + createAirflowDagPayload(jitRequest, runId + "-grant", "grant")); + airflowClient.triggerJitDag(dagId, runId + "-revoke", + createAirflowDagPayload(jitRequest, runId + "-revoke", "revoke")); jitRequest.setStatus(JitRequestStatus.APPROVED); diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java index afeb0499..b85e72ff 100644 --- a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackMessageElement.java @@ -2,6 +2,7 @@ package com.navi.infra.portal.v2.slackbotclient; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; import com.navi.infra.portal.dto.slack.SlackMessageText; import lombok.Data; import lombok.NoArgsConstructor; @@ -16,7 +17,8 @@ public class SlackMessageElement { private SlackMessageText text; // Should constitute of SlackMessageText private String style; // Example: primary, danger private String value; - private String action_id; // Refers to slackbotclient's internal action_id + @JsonProperty("action_id") + private String actionId; // Refers to slackbotclient's internal action_id public SlackMessageElement( SlackElementType type, @@ -29,7 +31,7 @@ public class SlackMessageElement { this.text = text; this.style = style.type; this.value = value; - this.action_id = actionId; + this.actionId = actionId; } /* elements": [ diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java index 14601716..18b481f6 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -1,10 +1,10 @@ package com.navi.infra.portal.v2.jit.service; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; @@ -25,9 +25,7 @@ import com.navi.infra.portal.v2.team.TeamService; import java.io.IOException; import java.time.LocalDateTime; import java.util.List; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.mockito.stubbing.Answer; public class JitServiceImplTest { @@ -43,10 +41,11 @@ public class JitServiceImplTest { private final UserService userService = mock(UserService.class); private final RoleService roleService = mock(RoleService.class); private final TeamService teamService = mock(TeamService.class); + private final ObjectMapper objectMapper = new ObjectMapper(); JitServiceImpl jitServiceImpl = new JitServiceImpl(jitRequestRepository, jitApprovalsRepository, - slackBotUtil, authUtil, airflowClient, slackBotClient, userService, roleService, - teamService); + slackBotUtil, authUtil, airflowClient, slackBotClient, objectMapper, userService, + roleService, teamService); User requestedFor = new User(); User requestedBy = new User(); JitRequestDto jitRequestDto = new JitRequestDto("alpha@one.com", "beta@two.com", From 5b58f59d6203afd76356a3b8c8a0fdc3ec9cb346 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 5 Apr 2024 22:24:02 +0530 Subject: [PATCH 036/108] INFRA-2219 | Harinder | Updating application properties default values as just in time and slackbot won't be interacting with all the clusters as of now --- src/main/resources/application-dev.properties | 5 +++++ src/main/resources/application.properties | 6 +++--- src/test/resources/application.properties | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index d139e73a..750e5b75 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -33,3 +33,8 @@ airflow.url=${AIRFLOW_URL} airflow.token=${AIRFLOW_AUTH_TOKEN} service-dump.dag.id=${SERVICE_DUMP_DAG_ID:kubectl_get_pod} service-dump.image.name=${SERVICE_DUMP_IMAGE_NAME:193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/openjdk:11.0.16-user4k} + +#Just In Time Access +slackbot.token=${SLACK_BOT_TOKEN:xoxb-format-12345} +jit.dag.id=${JIT_DAG_ID:jit_dag} +jit.slack.common.channel.id=${JIT_COMMON_CHANNEL:C06NDTBFA1G} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 71df9af8..3bf27ca5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -73,6 +73,6 @@ aws.profile=${AWS_PROFILE:default} spring.mvc.async.request-timeout=1800000 jit.number_of_prod_approvals=2 jit.number_of_nonprod_approvals=1 -slackbot.token=${SLACK_BOT_TOKEN} -jit.dag.id=${JIT_DAG_ID} -jit.slack.common.channel.id=C06NDTBFA1G \ No newline at end of file +slackbot.token=${SLACK_BOT_TOKEN:xoxb-format-12345} +jit.dag.id=${JIT_DAG_ID:jit_dag} +jit.slack.common.channel.id=${JIT_COMMON_CHANNEL:C0000000000} \ No newline at end of file diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 5303953a..8e2deed1 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -61,9 +61,9 @@ extraResource.list=database,docdb,elasticCache,aws_access,dynamodb,s3_buckets,de airflow.url=${AIRFLOW_URL:http://localhost:9090} airflow.token=${AIRFLOW_AUTH_TOKEN:something} service-dump.dag.id=${SERVICE_DUMP_DAG_ID:kubectl_get_pod} -jit.dag.id=${JIT_DAG_ID:jit_dag} +jit.dag.id=${JIT_DAG_ID:jit_dummy} jit.number_of_prod_approvals=2 jit.number_of_nonprod_approvals=1 -jit.slack.common.channel.id=C06NDTBFA1G +jit.slack.common.channel.id=C0000000000 slackbot.token=xoxb-676123123123-123123123123-123123123123-123123123123 service-dump.image.name=${SERVICE_DUMP_IMAGE_NAME:193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/jdk11-diagnostic:va39edbc8ebfbe68aedb776566e11b88cb4920d75} From dad178706219bb8548c726538a6c41ae19a65002 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 5 Apr 2024 22:54:38 +0530 Subject: [PATCH 037/108] INFRA-2219 | Harinder | Updating just in time access environment variables in manifest --- deployment_manifest.json | 12 ++++++++++++ gi_deployment_manifest.json | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/deployment_manifest.json b/deployment_manifest.json index c688ed05..4599f12c 100644 --- a/deployment_manifest.json +++ b/deployment_manifest.json @@ -125,6 +125,18 @@ { "name": "SERVICE_DUMP_DAG_ID", "value": "$SERVICE_DUMP_DAG_ID" + }, + { + "name": "SLACK_BOT_TOKEN", + "value": "$SLACK_BOT_TOKEN" + }, + { + "name": "JIT_DAG_ID", + "value": "$JIT_DAG_ID" + }, + { + "name": "JIT_COMMON_CHANNEL", + "value": "$JIT_COMMON_CHANNEL" } ], "namespace": "$NAMESPACE", diff --git a/gi_deployment_manifest.json b/gi_deployment_manifest.json index 3974a287..4d488715 100644 --- a/gi_deployment_manifest.json +++ b/gi_deployment_manifest.json @@ -88,6 +88,18 @@ { "name": "DOCKER_REGISTRY_NAMESPACE", "value": "$DOCKER_REGISTRY_NAMESPACE" + }, + { + "name": "SLACK_BOT_TOKEN", + "value": "$SLACK_BOT_TOKEN" + }, + { + "name": "JIT_DAG_ID", + "value": "$JIT_DAG_ID" + }, + { + "name": "JIT_COMMON_CHANNEL", + "value": "$JIT_COMMON_CHANNEL" } ], "namespace": "$NAMESPACE", From b52d6992c3535f1042456fba74d1e5bd8b1b659a Mon Sep 17 00:00:00 2001 From: Ashvin Sharma Date: Fri, 5 Apr 2024 23:05:49 +0530 Subject: [PATCH 038/108] INFRA-809 | Ashvin | Modify fields to fix the output files --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 5f127fe3..96f59de7 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 5f127fe31f98d837c81669d4566fbc515e7cfafe +Subproject commit 96f59de7cc8c50b9135138c0df9abf350ed89938 From 93eae0801d8e3f1dc1680fed8bd57e42c5f230ad Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Tue, 9 Apr 2024 15:57:21 +0530 Subject: [PATCH 039/108] INFRA-3114 | Harinder | Adding user that will be used by just in time(jit) slackbot --- .../db/migration/V1.74__Add_jit_slackbot_user_and_token.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/main/resources/db/migration/V1.74__Add_jit_slackbot_user_and_token.sql diff --git a/src/main/resources/db/migration/V1.74__Add_jit_slackbot_user_and_token.sql b/src/main/resources/db/migration/V1.74__Add_jit_slackbot_user_and_token.sql new file mode 100644 index 00000000..b9408a8a --- /dev/null +++ b/src/main/resources/db/migration/V1.74__Add_jit_slackbot_user_and_token.sql @@ -0,0 +1 @@ +INSERT INTO users values(default, now(), now(), 'jit-slackbot@jit.com', 'Just In Time Access Slackbot User'); \ No newline at end of file From a6f6dafcc326f5d33dd5ccc24967e91d9c9a8b8a Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Tue, 9 Apr 2024 19:28:38 +0530 Subject: [PATCH 040/108] INFRA-2787 | Harinder | [SB] Fix for command injection in name field --- src/main/resources/jsonschema/manifest.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/resources/jsonschema/manifest.json b/src/main/resources/jsonschema/manifest.json index cba9eaf3..0f96a840 100644 --- a/src/main/resources/jsonschema/manifest.json +++ b/src/main/resources/jsonschema/manifest.json @@ -46,7 +46,9 @@ }, "name": { "type": "string", - "minLength": 1 + "minLength": 1, + "maxLength": 63, + "pattern": "/^[a-z][a-z0-9\\-.]*[a-z]$/" }, "team": { "type": "object", From 18a9c58b08f2c2c2cb74832945ed1f388a3e08b1 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Wed, 10 Apr 2024 02:41:10 +0530 Subject: [PATCH 041/108] INFRA-2219 | Harinder | Add outbound connectivity to slack.com (#876) --- deployment_manifest.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deployment_manifest.json b/deployment_manifest.json index 4599f12c..358fbfdd 100644 --- a/deployment_manifest.json +++ b/deployment_manifest.json @@ -157,7 +157,8 @@ } ], "allowEgress": [ - "*.elastic-stack.svc.cluster.local" + "*.elastic-stack.svc.cluster.local", + "*.slack.com" ], "healthChecks": { "readinessCheck": { From 8634add292af0a8d8476e4c03c39252c9b8892f3 Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Wed, 10 Apr 2024 08:25:11 +0530 Subject: [PATCH 042/108] INFRA-809 | Ashvin | Fix local sandbox (#877) Because image was of type string and not *string the zero value of it is an empty string which messed up with how we decide putting busybox image in local sandbox. Context: https://go-navi.slack.com/archives/C03B0RHGNBE/p1712658391494339 --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 9cacae73..23fa10a9 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 9cacae734cf4ec6c6fb82707169b25430f960fcc +Subproject commit 23fa10a97111716fdf360d096d5c016b19b58a7e From 2d732a4501dc16939ee94f1eeb15d2f9983e5a9a Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 10 Apr 2024 11:50:19 +0530 Subject: [PATCH 043/108] INFRA-3139 | Dhruv | check for internal duplication of endpoint in manifest --- .../service/manifest/ManifestService.java | 55 ++++++++++++++----- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index c5550a9b..46f19d3a 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -55,6 +55,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.apache.commons.text.StringSubstitutor; @@ -212,7 +213,6 @@ public class ManifestService { final Manifest newManifest; if (hasDifference(difference)) { logManifestDifference(manifest, oldManifest); - processLoadBalancers(manifest, oldManifest); newManifest = saveManifestWithoutSecrets(manifest); newManifest.addRedactedValuesToSuperSecrets(); @@ -239,7 +239,6 @@ public class ManifestService { log.info("Manifest does not have deployment or flink"); return; } - final var findGroupNameRequest = FindGroupNameRequest.builder() .newLbs(newLbs) .oldLbs(oldLbs) @@ -496,7 +495,43 @@ public class ManifestService { var savedManifest = saveManifestWithAudit(manifest, secretsVersion, superSecretsVersion); return addGivenSecrets(savedManifest, secrets); } + private List getEndpointsFromCurrentManifest(Manifest manifest) { + return manifest.getDeployment() + .getLoadBalancers() + .stream() + .map(LoadBalancer::getEndpoint) + .collect(Collectors.toList()); + } + private void checkForExternalEndpointsDuplicates( + Manifest manifest, List allEndpointsInCurrentManifest) + { + Set allEndpointsExceptInParentManifest = getAllEndpointsNotIn(manifest.getId()); + List externalDuplicates = allEndpointsInCurrentManifest.stream() + .filter(allEndpointsExceptInParentManifest::contains) + .collect(Collectors.toList()); + + if (!externalDuplicates.isEmpty()) { + log.error("Duplicate load balancer endpoints found for {} - {}", + manifest.fullName(), externalDuplicates); + throw new DuplicateLoadBalancerEndpointException(externalDuplicates); + } + } + + private void checkForInternalEndpointsDuplicates( + Manifest manifest, List allEndpointsInCurrentManifest) + { + List internalDuplicates = allEndpointsInCurrentManifest.stream() + .filter(endpoint -> Collections.frequency(allEndpointsInCurrentManifest, endpoint) > 1) + .distinct() + .collect(Collectors.toList()); + + if (!internalDuplicates.isEmpty()) { + log.error("Duplicate load balancer endpoints found for {} - {}", + manifest.fullName(), internalDuplicates); + throw new DuplicateLoadBalancerEndpointException(internalDuplicates); + } + } private void validateLoadBalancer(Manifest manifest) { log.info("Validating load balancer for {}", manifest.fullName()); if (manifest.getDeployment() == null || @@ -507,19 +542,9 @@ public class ManifestService { return; } - final var allEndpointsExceptInParentManifest = getAllEndpointsNotIn(manifest.getId()); - final var manifestEndpoints = manifest.getDeployment() - .getLoadBalancers() - .stream() - .map(LoadBalancer::getEndpoint) - .filter(allEndpointsExceptInParentManifest::contains) - .collect(toList()); - - if (!manifestEndpoints.isEmpty()) { - log.error("Duplicate load balancer endpoints found for {} - {}", manifest.fullName(), - manifestEndpoints); - throw new DuplicateLoadBalancerEndpointException(manifestEndpoints); - } + List allEndpointsInCurrentManifest = getEndpointsFromCurrentManifest(manifest); + checkForExternalEndpointsDuplicates(manifest, allEndpointsInCurrentManifest); + checkForInternalEndpointsDuplicates(manifest, allEndpointsInCurrentManifest); log.info("No duplicate load balancer endpoints found for {}", manifest.fullName()); } From 2a4d8c2b019dcd782f51c7cfe917257604e3628f Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 10 Apr 2024 13:01:06 +0530 Subject: [PATCH 044/108] INFRA-3139 | Dhruv | add and fix tests --- .../ManifestServiceIntegrationTest.java | 22 ++ .../dev-testapp-duplicate-endpoint.json | 196 ++++++++++++++++++ .../manifest/dev-testapp-dynamicConfig.json | 4 +- .../manifest/dev-testapp-reducted-secret.json | 4 +- .../fixtures/manifest/dev-testapp.json | 4 +- ...estapp-dynamicConfig-create-or-update.json | 4 +- .../dev-testapp-dynamicConfig-render.json | 4 +- ...stapp-get-with-no-super-secret-access.json | 4 +- ...dev-testapp-get-without-secret-access.json | 4 +- .../expected_output/dev-testapp-get.json | 4 +- .../expected_output/dev-testapp-update.json | 4 +- 11 files changed, 236 insertions(+), 18 deletions(-) create mode 100644 src/test/resources/fixtures/manifest/dev-testapp-duplicate-endpoint.json diff --git a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java index cafa08ab..e12f604a 100644 --- a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java +++ b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java @@ -2,12 +2,15 @@ package com.navi.infra.portal.service; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.domain.manifest.Manifest; import com.navi.infra.portal.domain.manifest.ManifestAudit; import com.navi.infra.portal.dto.manifest.ManifestResponse; +import com.navi.infra.portal.exceptions.DuplicateLoadBalancerEndpointException; +import com.navi.infra.portal.exceptions.KubernetesManifestException; import com.navi.infra.portal.provider.ExternalIntegrationProvider; import com.navi.infra.portal.service.manifest.ManifestService; import java.io.IOException; @@ -64,6 +67,25 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider false)); } + @Test + @WithMockUser(value = "admin_user", username = "admin@navi.com", authorities = { + "manifest:Infra:dev:.*:secret_write", "manifest:Infra:dev:.*:secret_read", + "manifest:Infra:dev:.*:write", "manifest:Infra:dev:.*:supersecret_write", + "manifest:Infra:dev:.*:supersecret_read", "manifest:Infra:dev:.*:read", + "manifest:Infra:dev:.*:substitute_secrets"}, password = "admin") + @Transactional + @DisplayName("Test Duplicate Endpoint while Manifest Create and Update") + void shouldThrowErrorWhileCreatingManifest() throws IOException { + Manifest manifestRequest = readFileToManifest("fixtures/manifest/dev-testapp-duplicate-endpoint.json"); + boolean thrown = false; + try { + manifestService.createOrUpdate(manifestRequest); + } catch (DuplicateLoadBalancerEndpointException e) { + thrown = true; + } + assertTrue(thrown); + } + @Test @WithMockUser(value = "admin_user", username = "admin@navi.com", authorities = { "manifest:Infra:dev:.*:secret_write", "manifest:Infra:dev:.*:secret_read", diff --git a/src/test/resources/fixtures/manifest/dev-testapp-duplicate-endpoint.json b/src/test/resources/fixtures/manifest/dev-testapp-duplicate-endpoint.json new file mode 100644 index 00000000..9858708c --- /dev/null +++ b/src/test/resources/fixtures/manifest/dev-testapp-duplicate-endpoint.json @@ -0,0 +1,196 @@ +{ + "name": "testapp", + "environment": "dev", + "metadata": { + "repo": "navi-medici/test", + "language": "Java", + "product": "lending", + "dataSensitivity": "PII_SPI", + "logCriticality": "AccessLogs", + "disasterRecovery": "True" + }, + "extraResources": { + "aws_access": { + "policies": [ + { + "actions": [ + "s3:*" + ], + "resource": "*" + } + ] + } + }, + "notification": { + "notification": { + "slack": [ + "#test-slackgroup-alert" + ] + } + }, + "environmentVariables": [ + { + "name": "secretVar1", + "value": "secretVar1Value", + "type": "SECRET", + "sha256": "random-sha" + }, + { + "name": "configVar1", + "value": "configVar1Value", + "type": "CONFIG", + "sha256": "random-sha" + }, + { + "name": "superSecretVar1", + "value": "superSecretVar1Value", + "type": "SUPER_SECRET", + "sha256": "random-sha" + }, + { + "name": "SOME_URL", + "value": "https://google.com", + "type": "CONFIG", + "sha256": "random-sha", + "allowEgress": true + } + ], + "deployment": { + "cluster": "spike.np.navi-tech.in", + "loadBalancers": [ + { + "name": "lb-1", + "endpoint": "test-app1.spike.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "slowStartDuration": 0, + "type": "alb" + }, + { + "name": "lb-2", + "endpoint": "test-app1.spike.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "slowStartDuration": 60, + "type": "alb" + }, + { + "endpoint": "dev-test.spike.navi-tech.in", + "extraSecurityGroups": [ + "testapp-sg-1" + ], + "accessPolicies": [ + "internetFacing" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + } + ], + "alerts": { + "elb4xx": { + "duration": "3m", + "severity": "critical", + "threshold": 1 + }, + "elb5xx": { + "duration": "3m", + "severity": "critical", + "threshold": 1 + }, + "http4xx": { + "duration": "3m", + "severity": "critical", + "threshold": 15 + }, + "http5xx": { + "duration": "3m", + "severity": "critical", + "threshold": 2 + }, + "latency": { + "duration": "3m", + "severity": "warning", + "threshold": 800 + }, + "prometheusRecordingRule": [] + }, + "instance": { + "cpu": 0.3, + "memory": "300Mi" + }, + "exposedPorts": [ + { + "name": "serviceport", + "port": 8080 + }, + { + "name": "metrics", + "port": 4001 + } + ], + "allowEgress": [ + "https://wow.com", + "https://google.com" + ], + "healthCheck": { + "livenessCheck": { + "path": "/actuator/health", + "port": "metrics", + "type": "http", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + }, + "readinessCheck": { + "port": "serviceport", + "type": "tcp", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + } + }, + "hpa": { + "maxReplicas": 4, + "minReplicas": 2 + }, + "namespace": "dev", + "securityGroup": [ + { + "ids": [ + "sg-08fa3d4297d46a0f4" + ], + "name": "testapp-sg-1", + "rules": [ + { + "toPort": 443, + "fromPort": 443, + "protocol": "tcp", + "description": "Allow https traffic", + "ingressCidr": [ + "1.1.1.1/32", + "2a0a:a440::/29", + "::/32" + ] + } + ] + } + ], + "timeout": 1500 + }, + "team": { + "name": "Infra" + }, + "labels": { + "micrometer-prometheus": "disabled" + }, + "cluster": "spike.np.navi-tech.in" +} diff --git a/src/test/resources/fixtures/manifest/dev-testapp-dynamicConfig.json b/src/test/resources/fixtures/manifest/dev-testapp-dynamicConfig.json index 2382532f..6a354224 100644 --- a/src/test/resources/fixtures/manifest/dev-testapp-dynamicConfig.json +++ b/src/test/resources/fixtures/manifest/dev-testapp-dynamicConfig.json @@ -65,7 +65,7 @@ "loadBalancers": [ { "name": "lb-1", - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app1.spike.navi-tech.in", "accessPolicies": [ "internal" ], @@ -75,7 +75,7 @@ }, { "name": "lb-2", - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app2.spike.navi-tech.in", "accessPolicies": [ "internal" ], diff --git a/src/test/resources/fixtures/manifest/dev-testapp-reducted-secret.json b/src/test/resources/fixtures/manifest/dev-testapp-reducted-secret.json index 65e13bfe..61965749 100644 --- a/src/test/resources/fixtures/manifest/dev-testapp-reducted-secret.json +++ b/src/test/resources/fixtures/manifest/dev-testapp-reducted-secret.json @@ -61,7 +61,7 @@ "deployment": { "loadBalancers": [ { - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app1.spike.navi-tech.in", "accessPolicies": [ "internal" ], @@ -70,7 +70,7 @@ "type": "alb" }, { - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app2.spike.navi-tech.in", "accessPolicies": [ "internal" ], diff --git a/src/test/resources/fixtures/manifest/dev-testapp.json b/src/test/resources/fixtures/manifest/dev-testapp.json index 8e64b9eb..e61a8420 100644 --- a/src/test/resources/fixtures/manifest/dev-testapp.json +++ b/src/test/resources/fixtures/manifest/dev-testapp.json @@ -60,7 +60,7 @@ "loadBalancers": [ { "name": "lb-1", - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app1.spike.navi-tech.in", "accessPolicies": [ "internal" ], @@ -71,7 +71,7 @@ }, { "name": "lb-2", - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app2.spike.navi-tech.in", "accessPolicies": [ "internal" ], diff --git a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-create-or-update.json b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-create-or-update.json index bf4ba7c4..911ce4ba 100644 --- a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-create-or-update.json +++ b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-create-or-update.json @@ -63,7 +63,7 @@ "loadBalancers": [ { "version": 0, - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app1.spike.navi-tech.in", "accessPolicies": [ "internal" ], @@ -73,7 +73,7 @@ }, { "version": 0, - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app2.spike.navi-tech.in", "accessPolicies": [ "internal" ], diff --git a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-render.json b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-render.json index c56dc352..5a494261 100644 --- a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-render.json +++ b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-dynamicConfig-render.json @@ -59,7 +59,7 @@ "deployment": { "loadBalancers": [ { - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app1.spike.navi-tech.in", "accessPolicies": [ "internal" ], @@ -68,7 +68,7 @@ "type": "alb" }, { - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app2.spike.navi-tech.in", "accessPolicies": [ "internal" ], diff --git a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get-with-no-super-secret-access.json b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get-with-no-super-secret-access.json index 0ba55233..c6e7d2d7 100644 --- a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get-with-no-super-secret-access.json +++ b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get-with-no-super-secret-access.json @@ -53,7 +53,7 @@ "deployment": { "loadBalancers": [ { - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app1.spike.navi-tech.in", "accessPolicies": [ "internal" ], @@ -62,7 +62,7 @@ "type": "alb" }, { - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app2.spike.navi-tech.in", "accessPolicies": [ "internal" ], diff --git a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get-without-secret-access.json b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get-without-secret-access.json index a6c2654c..1fea340a 100644 --- a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get-without-secret-access.json +++ b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get-without-secret-access.json @@ -54,7 +54,7 @@ "deployment": { "loadBalancers": [ { - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app1.spike.navi-tech.in", "accessPolicies": [ "internal" ], @@ -63,7 +63,7 @@ "type": "alb" }, { - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app2.spike.navi-tech.in", "accessPolicies": [ "internal" ], diff --git a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get.json b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get.json index c0c2cf7c..26997a28 100644 --- a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get.json +++ b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-get.json @@ -55,7 +55,7 @@ "loadBalancers": [ { "name": "lb-1", - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app1.spike.navi-tech.in", "accessPolicies": [ "internal" ], @@ -65,7 +65,7 @@ }, { "name": "lb-2", - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app2.spike.navi-tech.in", "accessPolicies": [ "internal" ], diff --git a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-update.json b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-update.json index ef8bb794..3bbacd7e 100644 --- a/src/test/resources/fixtures/manifest/expected_output/dev-testapp-update.json +++ b/src/test/resources/fixtures/manifest/expected_output/dev-testapp-update.json @@ -59,7 +59,7 @@ { "name": "lb-1", "version": 0, - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app1.spike.navi-tech.in", "accessPolicies": [ "internal" ], @@ -70,7 +70,7 @@ { "name": "lb-2", "version": 0, - "endpoint": "test-app.spike.navi-tech.in", + "endpoint": "test-app2.spike.navi-tech.in", "accessPolicies": [ "internal" ], From 6ffd8a26c7a5be8401f45307314452ea9f75c075 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 10 Apr 2024 13:34:26 +0530 Subject: [PATCH 045/108] INFRA-3139 | Dhruv | fix pr comments --- .../portal/service/manifest/ManifestService.java | 12 +++++++----- .../service/ManifestServiceIntegrationTest.java | 12 ++++-------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index 46f19d3a..2f660aef 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -504,8 +504,8 @@ public class ManifestService { } private void checkForExternalEndpointsDuplicates( - Manifest manifest, List allEndpointsInCurrentManifest) - { + Manifest manifest, List allEndpointsInCurrentManifest + ) { Set allEndpointsExceptInParentManifest = getAllEndpointsNotIn(manifest.getId()); List externalDuplicates = allEndpointsInCurrentManifest.stream() .filter(allEndpointsExceptInParentManifest::contains) @@ -519,10 +519,11 @@ public class ManifestService { } private void checkForInternalEndpointsDuplicates( - Manifest manifest, List allEndpointsInCurrentManifest) - { + Manifest manifest, List allEndpointsInCurrentManifest + ) { + Set endpointSet = new HashSet<>(); List internalDuplicates = allEndpointsInCurrentManifest.stream() - .filter(endpoint -> Collections.frequency(allEndpointsInCurrentManifest, endpoint) > 1) + .filter(endpoint -> !endpointSet.add(endpoint)) .distinct() .collect(Collectors.toList()); @@ -532,6 +533,7 @@ public class ManifestService { throw new DuplicateLoadBalancerEndpointException(internalDuplicates); } } + private void validateLoadBalancer(Manifest manifest) { log.info("Validating load balancer for {}", manifest.fullName()); if (manifest.getDeployment() == null || diff --git a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java index e12f604a..9a282e76 100644 --- a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java +++ b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java @@ -76,14 +76,10 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider @Transactional @DisplayName("Test Duplicate Endpoint while Manifest Create and Update") void shouldThrowErrorWhileCreatingManifest() throws IOException { - Manifest manifestRequest = readFileToManifest("fixtures/manifest/dev-testapp-duplicate-endpoint.json"); - boolean thrown = false; - try { - manifestService.createOrUpdate(manifestRequest); - } catch (DuplicateLoadBalancerEndpointException e) { - thrown = true; - } - assertTrue(thrown); + Manifest manifestRequest = readFileToManifest( + "fixtures/manifest/dev-testapp-duplicate-endpoint.json"); + assertThrows(DuplicateLoadBalancerEndpointException.class, + () -> manifestService.createOrUpdate(manifestRequest));xw } @Test From 79f0e22ac21ea8257492a051b00ff1671cbed9bc Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 10 Apr 2024 13:41:28 +0530 Subject: [PATCH 046/108] INFRA-3139 | Dhruv | fix pr comments --- .../infra/portal/service/ManifestServiceIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java index 9a282e76..42812d77 100644 --- a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java +++ b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java @@ -79,7 +79,7 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider Manifest manifestRequest = readFileToManifest( "fixtures/manifest/dev-testapp-duplicate-endpoint.json"); assertThrows(DuplicateLoadBalancerEndpointException.class, - () -> manifestService.createOrUpdate(manifestRequest));xw + () -> manifestService.createOrUpdate(manifestRequest)); } @Test From cd5318e9756699b69c3868e94ad1f881a821f9a1 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 10 Apr 2024 15:27:33 +0530 Subject: [PATCH 047/108] INFRA-3139 | Dhruv | fix pr comments --- .../com/navi/infra/portal/service/manifest/ManifestService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index 2f660aef..ff036b13 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -495,6 +495,7 @@ public class ManifestService { var savedManifest = saveManifestWithAudit(manifest, secretsVersion, superSecretsVersion); return addGivenSecrets(savedManifest, secrets); } + private List getEndpointsFromCurrentManifest(Manifest manifest) { return manifest.getDeployment() .getLoadBalancers() From 0928c7c5587440f12147e21d3e4b4d05ce348c29 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Wed, 10 Apr 2024 19:30:43 +0530 Subject: [PATCH 048/108] INFRA-2220 | Harinder | Updating execution time in trigger dag function and removing grant window from jit slack message --- .../infra/portal/v2/jit/service/JitServiceImpl.java | 11 +++++++++-- .../navi/infra/portal/v2/jit/utils/SlackBotUtil.java | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 1d211219..8332debd 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -21,11 +21,16 @@ import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; import com.navi.infra.portal.v2.team.TeamService; import java.io.IOException; import java.net.ConnectException; +import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -133,8 +138,10 @@ class JitServiceImpl implements JitService { ) { LocalDateTime executionDate = action.equals("grant") ? jitRequest.getGrantAt() : jitRequest.getGrantAt().plusHours(jitRequest.getGrantWindow()); - String apacheTimeFormat = String.join("+", - executionDate.toString(), "05:30"); + + DateTimeFormatter iso8601Format = DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss'Z'"); + String apacheTimeFormat = executionDate.format(iso8601Format); + var payloadMap = Map.of("dag_run_id", runId, "execution_date", apacheTimeFormat, "conf", Map.of( diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index 7bb14fff..91ba66a8 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -27,11 +27,11 @@ public class SlackBotUtil { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format("Access request reviewed for user %s\n" + "\t*Vertical*\n" + "\t%s\n\n" + "\t*Environment*\t\t\t\t\t*Resource*\n" + "\t%s\t\t\t\t\t\t\t\t %s\n\n" - + "\t*Grant At/On*\t\t\t\t\t*Grant Window(In hours)*\n" + "\t%s\t\t %s\n\n" + + "\t*Grant At/On*\n" + "\t%s\n\n" + "Request status: %s", userEmail, jitRequest.getVertical().toString(), jitRequest.getEnvironment().toString(), jitRequest.getResourceType(), jitRequest.getGrantAt().truncatedTo(ChronoUnit.MINUTES), - jitRequest.getGrantWindow(), jitApproval.getAction().toString())); + jitApproval.getAction().toString())); SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( SlackMessageBlockType.SECTION, reviewRequestText, null); blocks.add(reviewRequestSection); From fa5d7e1f500425e6ad9402e07a0a3add3001cc46 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 12 Apr 2024 13:03:38 +0530 Subject: [PATCH 049/108] INFRA-2220 | Harinder | The last change in date time format started resulting in 400 on airflow APIs for JIT requests --- .../navi/infra/portal/v2/client/airflow/AirflowClient.java | 1 + .../com/navi/infra/portal/v2/jit/service/JitServiceImpl.java | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java b/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java index 272db6b9..6aa69295 100644 --- a/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java +++ b/src/main/java/com/navi/infra/portal/v2/client/airflow/AirflowClient.java @@ -110,6 +110,7 @@ public class AirflowClient { log.info("Triggering JIT DAG for runId: {}", runId); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); + log.info("Airflow JIT DAG response: {}", response); return objectMapper.readValue(response.body(), AirflowApiResponse.class); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 8332debd..29e2a7f2 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -139,7 +139,7 @@ class JitServiceImpl implements JitService { LocalDateTime executionDate = action.equals("grant") ? jitRequest.getGrantAt() : jitRequest.getGrantAt().plusHours(jitRequest.getGrantWindow()); - DateTimeFormatter iso8601Format = DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss'Z'"); + DateTimeFormatter iso8601Format = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"); String apacheTimeFormat = executionDate.format(iso8601Format); var payloadMap = Map.of("dag_run_id", runId, @@ -229,7 +229,7 @@ class JitServiceImpl implements JitService { jitRequest.getRequestedFor().getEmail(), jitRequest.getResourceType(), jitRequest.getResourceAction()); validateGrantTime(jitRequest); - airflowClient.triggerJitDag(dagId, runId + "-revoke", + airflowClient.triggerJitDag(dagId, runId + "-grant", createAirflowDagPayload(jitRequest, runId + "-grant", "grant")); airflowClient.triggerJitDag(dagId, runId + "-revoke", createAirflowDagPayload(jitRequest, runId + "-revoke", "revoke")); @@ -369,7 +369,6 @@ class JitServiceImpl implements JitService { throw new RuntimeException(e); } }); - jitRequestRepository.save(jitRequest); } From 9ff6b1c5dd4c2fafcf1c46723cc1d9847b4f0a39 Mon Sep 17 00:00:00 2001 From: Ankit Bhardwaj Bhardwaj Date: Mon, 15 Apr 2024 16:36:37 +0530 Subject: [PATCH 050/108] INFRA-3158 | Ankit Bhardwaj | add amc nonprod cluster values (#884) --- kutegen | 2 +- src/main/resources/jsonschema/manifest.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/kutegen b/kutegen index 23fa10a9..edd7b8c9 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 23fa10a97111716fdf360d096d5c016b19b58a7e +Subproject commit edd7b8c963854ff437c7255f85eff59b6a1b86fb diff --git a/src/main/resources/jsonschema/manifest.json b/src/main/resources/jsonschema/manifest.json index cf0eade2..99205b75 100644 --- a/src/main/resources/jsonschema/manifest.json +++ b/src/main/resources/jsonschema/manifest.json @@ -41,7 +41,8 @@ "aps1.prod.ml.navi-tech.in", "aps1.np.navi-ppl.in", "aps1.prod.navi-ppl.in", - "aps1.prod.navi-amc.in" + "aps1.prod.navi-amc.in", + "aps1.np.navi-amc.in" ] }, "name": { From fce6546d8a5e6516c2dbbbe33e3da84c98f32b21 Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Tue, 16 Apr 2024 02:48:25 +0530 Subject: [PATCH 051/108] INFRA-809 | Ashvin | Make deployment_manifest.json compliant with kutegen (#882) --- deployment_manifest.json | 249 +++++++++++++++++++-------------------- 1 file changed, 124 insertions(+), 125 deletions(-) diff --git a/deployment_manifest.json b/deployment_manifest.json index 358fbfdd..78b6c86f 100644 --- a/deployment_manifest.json +++ b/deployment_manifest.json @@ -1,4 +1,5 @@ { + "name": "deployment-portal-backend", "environment": "$ENVIRONMENT", "metadata": { "repo": "navi-infra/deployment-portal-backend", @@ -8,137 +9,135 @@ "disasterRecovery": "True" }, "cluster": "$CLUSTER", + "environmentVariables": [ + { + "name": "ENVIRONMENT", + "value": "$ENVIRONMENT" + }, + { + "name": "DATASOURCE_URL", + "value": "$DATASOURCE_URL" + }, + { + "name": "DATASOURCE_PASSWORD", + "value": "$DATASOURCE_PASSWORD" + }, + { + "name": "DATASOURCE_USERNAME", + "value": "$DATASOURCE_USERNAME" + }, + { + "name": "OKTA_CLIENT_ID", + "value": "$OKTA_CLIENT_ID" + }, + { + "name": "OKTA_CLIENT_SECRET", + "value": "$OKTA_CLIENT_SECRET" + }, + { + "name": "JVM_OPTS", + "value": "$JVM_OPTS" + }, + { + "name": "OKTA_URL", + "value": "$OKTA_URL" + }, + { + "name": "ALLOWED_ORIGINS", + "value": "$ALLOWED_ORIGINS" + }, + { + "name": "VAULT_ADDRESS", + "value": "$VAULT_ADDRESS" + }, + { + "name": "VAULT_METATOKEN", + "value": "$VAULT_METATOKEN" + }, + { + "name": "DDL_AUTO", + "value": "$DDL_AUTO" + }, + { + "name": "KUBE_CONFIG", + "value": "$KUBE_CONFIG" + }, + { + "name": "VAULT_AUTH_METHOD", + "value": "$VAULT_AUTH_METHOD" + }, + { + "name": "VAULT_KUBE_PROVIDER", + "value": "$VAULT_KUBE_PROVIDER" + }, + { + "name": "VAULT_KUBE_ROLE", + "value": "$VAULT_KUBE_ROLE" + }, + { + "name": "VAULT_KUBE_TOKEN_CRON", + "value": "$VAULT_KUBE_TOKEN_CRON" + }, + { + "name": "PORTAL_VERTICAL", + "value": "$PORTAL_VERTICAL" + }, + { + "name": "SLACK_WEBHOOK_URL", + "value": "$SLACK_WEBHOOK_URL" + }, + { + "name": "DOCKER_REGISTRY_NAMESPACE", + "value": "$DOCKER_REGISTRY_NAMESPACE" + }, + { + "name": "JWT_SECRET_KEY", + "value": "$JWT_SECRET_KEY" + }, + { + "name": "TEAMS_LIST_VAULT", + "value": "$TEAMS_LIST_VAULT" + }, + { + "name": "ELASTIC_APM_SERVER_URLS", + "value": "$ELASTIC_APM_SERVER_URLS" + }, + { + "name": "ELASTIC_APM_ENVIRONMENT", + "value": "$ELASTIC_APM_ENVIRONMENT" + }, + { + "name": "AIRFLOW_URL", + "value": "$AIRFLOW_URL" + }, + { + "name": "AIRFLOW_AUTH_TOKEN", + "value": "$AIRFLOW_AUTH_TOKEN" + }, + { + "name": "SERVICE_DUMP_DAG_ID", + "value": "$SERVICE_DUMP_DAG_ID" + }, + { + "name": "SLACK_BOT_TOKEN", + "value": "$SLACK_BOT_TOKEN" + }, + { + "name": "JIT_DAG_ID", + "value": "$JIT_DAG_ID" + }, + { + "name": "JIT_COMMON_CHANNEL", + "value": "$JIT_COMMON_CHANNEL" + } + ], "deployment": { - "cluster": "$CLUSTER", "serviceAccount": true, - "name": "deployment-portal-backend", "instance": { "count": 2, "cpu": 1, "memory": "3Gi" }, - "environmentVariables": [ - { - "name": "ENVIRONMENT", - "value": "$ENVIRONMENT" - }, - { - "name": "DATASOURCE_URL", - "value": "$DATASOURCE_URL" - }, - { - "name": "DATASOURCE_PASSWORD", - "value": "$DATASOURCE_PASSWORD" - }, - { - "name": "DATASOURCE_USERNAME", - "value": "$DATASOURCE_USERNAME" - }, - { - "name": "OKTA_CLIENT_ID", - "value": "$OKTA_CLIENT_ID" - }, - { - "name": "OKTA_CLIENT_SECRET", - "value": "$OKTA_CLIENT_SECRET" - }, - { - "name": "JVM_OPTS", - "value": "$JVM_OPTS" - }, - { - "name": "OKTA_URL", - "value": "$OKTA_URL" - }, - { - "name": "ALLOWED_ORIGINS", - "value": "$ALLOWED_ORIGINS" - }, - { - "name": "VAULT_ADDRESS", - "value": "$VAULT_ADDRESS" - }, - { - "name": "VAULT_METATOKEN", - "value": "$VAULT_METATOKEN" - }, - { - "name": "DDL_AUTO", - "value": "$DDL_AUTO" - }, - { - "name": "KUBE_CONFIG", - "value": "$KUBE_CONFIG" - }, - { - "name": "VAULT_AUTH_METHOD", - "value": "$VAULT_AUTH_METHOD" - }, - { - "name": "VAULT_KUBE_PROVIDER", - "value": "$VAULT_KUBE_PROVIDER" - }, - { - "name": "VAULT_KUBE_ROLE", - "value": "$VAULT_KUBE_ROLE" - }, - { - "name": "VAULT_KUBE_TOKEN_CRON", - "value": "$VAULT_KUBE_TOKEN_CRON" - }, - { - "name": "PORTAL_VERTICAL", - "value": "$PORTAL_VERTICAL" - }, - { - "name": "SLACK_WEBHOOK_URL", - "value": "$SLACK_WEBHOOK_URL" - }, - { - "name": "DOCKER_REGISTRY_NAMESPACE", - "value": "$DOCKER_REGISTRY_NAMESPACE" - }, - { - "name": "JWT_SECRET_KEY", - "value": "$JWT_SECRET_KEY" - }, - { - "name": "TEAMS_LIST_VAULT", - "value": "$TEAMS_LIST_VAULT" - }, - { - "name": "ELASTIC_APM_SERVER_URLS", - "value": "$ELASTIC_APM_SERVER_URLS" - }, - { - "name": "ELASTIC_APM_ENVIRONMENT", - "value": "$ELASTIC_APM_ENVIRONMENT" - }, - { - "name": "AIRFLOW_URL", - "value": "$AIRFLOW_URL" - }, - { - "name": "AIRFLOW_AUTH_TOKEN", - "value": "$AIRFLOW_AUTH_TOKEN" - }, - { - "name": "SERVICE_DUMP_DAG_ID", - "value": "$SERVICE_DUMP_DAG_ID" - }, - { - "name": "SLACK_BOT_TOKEN", - "value": "$SLACK_BOT_TOKEN" - }, - { - "name": "JIT_DAG_ID", - "value": "$JIT_DAG_ID" - }, - { - "name": "JIT_COMMON_CHANNEL", - "value": "$JIT_COMMON_CHANNEL" - } - ], "namespace": "$NAMESPACE", "exposedPorts": [ { @@ -250,5 +249,5 @@ "labels": { "micrometer-prometheus": "enabled" }, - "version": "v1" + "infraVertical": "lending" } From 402d9eec692f3b46e5f753045ef63e89b88ddcfa Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Tue, 16 Apr 2024 03:54:24 +0530 Subject: [PATCH 052/108] INFRA-809 | Ashvin | Fixes wrong version format (#885) * INFRA-809 | Ashvin | Make deployment_manifest.json compliant with kutegen * INFRA-809 | Ashvin | Fixes wrong version format https://infra-pipelines.cmd.navi-tech.in/go/tab/build/detail/deployment-portal-backend-dev-deployment/859/deploy/3/deploy * INFRA-809 | Ashvin | Fixes wrong version format https://infra-pipelines.cmd.navi-tech.in/go/tab/build/detail/deployment-portal-backend-dev-deployment/859/deploy/3/deploy --- go.work | 2 +- kutegen | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go.work b/go.work index 40b57856..a5674b64 100644 --- a/go.work +++ b/go.work @@ -1,3 +1,3 @@ -go 1.21.0 +go 1.21 use ./kutegen diff --git a/kutegen b/kutegen index edd7b8c9..6895c2a7 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit edd7b8c963854ff437c7255f85eff59b6a1b86fb +Subproject commit 6895c2a70793f35ebf61df6b2b34cf0eb9cfcde6 From 29963b7696d9c4315823a862ddb65c6ae9bb8c9a Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Tue, 16 Apr 2024 11:01:20 +0530 Subject: [PATCH 053/108] INFRA-809 | Ashvin | Make deployment_manifest.json compliant with kutegen (#886) --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 6895c2a7..671c84b2 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 6895c2a70793f35ebf61df6b2b34cf0eb9cfcde6 +Subproject commit 671c84b2022cd6071a1942cdad1803135ce2b443 From 8fc7e082ad7d87c167aef37a6f8a5cf0664628de Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Tue, 16 Apr 2024 14:55:42 +0530 Subject: [PATCH 054/108] INFRA-809 | Ashvin | Fix env var substitution (#887) Earlier the implementation of env var substitution splits key value pair of env var (in format KEY=VALUE) on the basis of equals sign. There is a possibility that equals maybe a valid character in the value and thus now we will only split the first equals. This will fix this pipeline: https://infra-pipelines.cmd.navi-tech.in/go/tab/build/detail/deployment-portal-backend-dev-deployment/861/deploy/3/deploy --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 671c84b2..8f65a0e8 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 671c84b2022cd6071a1942cdad1803135ce2b443 +Subproject commit 8f65a0e83fdebac9e03f9532143ef67217316756 From 34af8a07b682dd2b48020aa72e64705f421f4ce9 Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Tue, 16 Apr 2024 16:14:06 +0530 Subject: [PATCH 055/108] INFRA-809 | Ashvin | Add roleName field in aws_access (#888) Fixes https://infra-pipelines.cmd.navi-tech.in/go/tab/build/detail/amc-deployment-portal-backend-cmd-deployment/140/deploy/4/deploy --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 8f65a0e8..ee17d557 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 8f65a0e83fdebac9e03f9532143ef67217316756 +Subproject commit ee17d5576b4105e69d9001685f32af7787879ad7 From 194916bf31520feafe602e656b6c29d6a7c10a76 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Tue, 16 Apr 2024 18:57:21 +0530 Subject: [PATCH 056/108] INFRA-2220 | Harinder | Preventing repeat requests, adding fields in slackbotmessageutil to help in formatting, adding information on required number of approvals per request and updating tests --- .../v2/jit/controller/JitController.java | 3 + .../jit/repository/JitRequestsRepository.java | 18 ++- .../portal/v2/jit/service/JitServiceImpl.java | 24 ++- .../portal/v2/jit/utils/SlackBotUtil.java | 150 ++++++++++++------ .../slackbotclient/SlackBotMessageBlock.java | 5 +- .../portal/v2/jit/utils/SlackBotUtilTest.java | 2 + 6 files changed, 148 insertions(+), 54 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java index 7e4d6992..b240441b 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java @@ -9,6 +9,7 @@ import java.net.ConnectException; import javax.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.dao.DuplicateKeyException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; @@ -38,6 +39,8 @@ public class JitController { return ResponseEntity.status(HttpStatus.CREATED).build(); } catch (IllegalArgumentException | IllegalStateException ex) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); + } catch (DuplicateKeyException ex) { + return ResponseEntity.status(HttpStatus.CONFLICT).build(); } catch (IOException ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java index 0953d36d..6dd8f5cf 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java @@ -1,11 +1,27 @@ package com.navi.infra.portal.v2.jit.repository; import com.navi.infra.portal.v2.jit.entity.JitRequest; +import java.time.LocalDateTime; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @Repository public interface JitRequestsRepository extends JpaRepository { + + @Query(value = "SELECT * FROM jit_requests WHERE requested_for_id = :requestedForId " + + "AND resource_type = :resourceType AND environment = :env " + + "AND resource_action = :resourceAction " + + "AND grant_at <= :grantAt " + + "AND grant_at + interval '1 hour' * grant_window >= :grantAt " + + "AND status='PENDING'", + nativeQuery = true) + List findDuplicateRequestsByUser( + Long requestedForId, + String resourceType, + String env, + String resourceAction, + LocalDateTime grantAt + ); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 29e2a7f2..e6c6dc1a 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -21,22 +21,19 @@ import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; import com.navi.infra.portal.v2.team.TeamService; import java.io.IOException; import java.net.ConnectException; -import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; -import java.time.OffsetDateTime; import java.time.ZoneId; -import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; +import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -66,6 +63,14 @@ class JitServiceImpl implements JitService { @Value("${jit.slack.common.channel.id}") private String commonChannelId; + private boolean duplicateRequest(JitRequest jitRequest) { + List existingDuplicates = jitRequestRepository.findDuplicateRequestsByUser( + jitRequest.getRequestedFor().getId(), jitRequest.getResourceType(), + jitRequest.getEnvironment().toString(), jitRequest.getResourceAction(), + jitRequest.getGrantAt()); + return !existingDuplicates.isEmpty(); + } + private void updateReviewerDmOnSlack( User reviewer, JitRequest jitRequest, @@ -107,6 +112,12 @@ class JitServiceImpl implements JitService { userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); } + private void updateRequestorRequestNotAllowed(JitRequest jitRequest) throws IOException { + SlackBotAttachment personalMessage = slackBotUtil.getRequestorRequestNotAllowedDm(jitRequest); + slackBotClient.postMessage( + userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); + } + private void updateChannelOnSlack( JitRequest jitRequest, List pendingReviewers, @@ -324,6 +335,11 @@ class JitServiceImpl implements JitService { // Map request DTO to JitRequest Entity and save in DB JitRequest jitRequest = mapToJitRequest(jitRequestDto); + if (duplicateRequest(jitRequest)) { + updateRequestorRequestNotAllowed(jitRequest); + throw new DuplicateKeyException("Repeat request not allowed"); + } + // Determine the reviewers based on REQUEST List reviewers = authUtil.getReviewers(jitRequestDto) .stream() diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index 91ba66a8..f2b4f294 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -12,52 +12,73 @@ import com.navi.infra.portal.v2.slackbotclient.SlackElementType; import com.navi.infra.portal.v2.slackbotclient.SlackMessageElement; import java.time.temporal.ChronoUnit; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.springframework.stereotype.Component; @Component public class SlackBotUtil { - public SlackBotAttachment getReviewerDm( - String userEmail, JitRequest jitRequest, JitApproval jitApproval, boolean actionEnabled, - SlackColor color + private ArrayList createInfoFields( + String userEmail, + JitRequest jitRequest, + JitApproval jitApproval ) { - ArrayList blocks = new ArrayList<>(); + return new ArrayList<>(Arrays.asList( + createField("Request ID", jitRequest.getId().toString()), + createField("User", userEmail), + createField("Environment", jitRequest.getEnvironment().toString()), + createField("Resource", jitRequest.getResourceType()), + createField("Grant At/On", + jitRequest.getGrantAt().truncatedTo(ChronoUnit.MINUTES).toString()), + createField("Status", jitApproval.getAction().toString()) + )); + } + + private ArrayList createActionButtons(JitApproval jitApproval) { + return new ArrayList<>(Arrays.asList( + createButton("Approve", jitApproval.getId().toString(), "actionApprove", + SlackElementStyle.PRIMARY), + createButton("Reject", jitApproval.getId().toString(), "actionReject", + SlackElementStyle.DANGER) + )); + } + + private SlackMessageText createField(String title, String text) { + return new SlackMessageText(SlackMessageTextType.MARKDOWN, + String.format("*%s*\n%s", title, text)); + } + + private SlackMessageElement createButton( + String text, + String value, + String actionId, + SlackElementStyle style + ) { + return new SlackMessageElement(SlackElementType.BUTTON, + new SlackMessageText(SlackMessageTextType.PLAINTEXT, text), + style, value, actionId); + } + + public SlackBotAttachment getReviewerDm( + String userEmail, JitRequest jitRequest, JitApproval jitApproval, + boolean actionEnabled, SlackColor color + ) { + + ArrayList infoFields = createInfoFields(userEmail, jitRequest, + jitApproval); + ArrayList actionButtons = + actionEnabled ? createActionButtons(jitApproval) : null; - SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, - String.format("Access request reviewed for user %s\n" + "\t*Vertical*\n" + "\t%s\n\n" - + "\t*Environment*\t\t\t\t\t*Resource*\n" + "\t%s\t\t\t\t\t\t\t\t %s\n\n" - + "\t*Grant At/On*\n" + "\t%s\n\n" - + "Request status: %s", userEmail, jitRequest.getVertical().toString(), - jitRequest.getEnvironment().toString(), jitRequest.getResourceType(), - jitRequest.getGrantAt().truncatedTo(ChronoUnit.MINUTES), - jitApproval.getAction().toString())); SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( - SlackMessageBlockType.SECTION, reviewRequestText, null); + SlackMessageBlockType.SECTION, null, null, infoFields); + + SlackBotMessageBlock reviewRequestAction = actionButtons != null ? new SlackBotMessageBlock( + SlackMessageBlockType.ACTIONS, null, actionButtons, null) : null; + + ArrayList blocks = new ArrayList<>(); blocks.add(reviewRequestSection); - - if (actionEnabled) { - SlackMessageText approveText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, - "Approve"); - SlackMessageElement approveButton = new SlackMessageElement(SlackElementType.BUTTON, - approveText, SlackElementStyle.PRIMARY, - jitApproval.getId().toString(), - "actionApprove"); - - SlackMessageText rejectText = new SlackMessageText(SlackMessageTextType.PLAINTEXT, - "Reject"); - SlackMessageElement rejectButton = new SlackMessageElement(SlackElementType.BUTTON, - rejectText, SlackElementStyle.DANGER, - jitApproval.getId().toString(), - "actionReject"); - - ArrayList elements = new ArrayList<>(); - elements.add(approveButton); - elements.add(rejectButton); - - SlackBotMessageBlock reviewRequestAction = new SlackBotMessageBlock( - SlackMessageBlockType.ACTIONS, null, elements); - + if (reviewRequestAction != null) { blocks.add(reviewRequestAction); } @@ -75,13 +96,21 @@ public class SlackBotUtil { SlackColor color ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, - String.format("Access request raised for user %s\n" + "\tPending Reviewers: %s\n" - + "\tApproved Reviewers: %s\n" + "\tRejected Reviewers: %s\n" - + "\tCurrent Status: %s\n", userEmail, pendingReviewers.toString(), - approvedReviewers.toString(), rejectedReviewers.toString(), requestStatus)); + String.format("Access request *#%s* raised for user %s\n" + + "\tPending Reviewers: %s\n" + + "\tApproved Reviewers: %s\n" + + "\tRejected Reviewers: %s\n" + + "\tApprovals required: %s\n" + + "\tCurrent Status: %s\n", + jitRequest.getId().toString(), userEmail, + String.join(", ", pendingReviewers), + String.join(", ", approvedReviewers), + String.join(", ", rejectedReviewers), + jitRequest.getEnvironment().approvals, + requestStatus)); SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( - SlackMessageBlockType.SECTION, reviewRequestText, null); + SlackMessageBlockType.SECTION, reviewRequestText, null, null); ArrayList blocks = new ArrayList<>(); blocks.add(reviewRequestSection); @@ -95,7 +124,7 @@ public class SlackBotUtil { closeText, SlackElementStyle.DANGER, jitRequest.getId().toString(), "actionClose"); elements.add(closeButton); SlackBotMessageBlock reviewRequestAction = new SlackBotMessageBlock( - SlackMessageBlockType.ACTIONS, null, elements); + SlackMessageBlockType.ACTIONS, null, elements, null); blocks.add(reviewRequestAction); } @@ -112,7 +141,25 @@ public class SlackBotUtil { jitRequest.getTeam().getName())); SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( - SlackMessageBlockType.SECTION, reviewRequestText, null); + SlackMessageBlockType.SECTION, reviewRequestText, null, null); + + ArrayList blocks = new ArrayList<>(); + blocks.add(reviewRequestSection); + + return new SlackBotAttachment(SlackColor.REJECTED.color, blocks); + } + + public SlackBotAttachment getRequestorRequestNotAllowedDm( + JitRequest jitRequest + ) { + SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, + String.format( + "Request for same resource in the specified window already exists. " + + "Contact Cloud Platform oncall if issue persists", + jitRequest.getTeam().getName())); + + SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( + SlackMessageBlockType.SECTION, reviewRequestText, null, null); ArrayList blocks = new ArrayList<>(); blocks.add(reviewRequestSection); @@ -129,14 +176,21 @@ public class SlackBotUtil { SlackColor color ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, - String.format("Access request raised for user %s\n" + "\tPending Reviewers: %s\n" - + "\tApproved By: %s\n\tRejected By: %s\n\tCurrent status: %s", email, - pendingReviewers.toString(), - approvedReviewers.toString(), rejectedReviewers.toString(), + String.format("Access request *#%s* raised for user %s\n" + + "\tPending Reviewers: %s\n" + + "\tApproved By: %s\n" + + "\tRejected By: %s\n" + + "\tApprovals required: %s\n" + + "\tCurrent status: %s", + jitRequest.getId().toString(), email, + String.join(", ", pendingReviewers), + String.join(", ", approvedReviewers), + String.join(", ", rejectedReviewers), + jitRequest.getEnvironment().approvals, jitRequest.getStatus().toString())); SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( - SlackMessageBlockType.SECTION, reviewRequestText, null); + SlackMessageBlockType.SECTION, reviewRequestText, null, null); ArrayList blocks = new ArrayList<>(); blocks.add(reviewRequestSection); diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java index 9210294a..ab760daa 100644 --- a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotMessageBlock.java @@ -18,15 +18,18 @@ public class SlackBotMessageBlock { private String type; // Example: button private SlackMessageText text; // Should constitute of SlackBotMessageText private ArrayList elements; + private ArrayList fields; public SlackBotMessageBlock( SlackMessageBlockType type, SlackMessageText text, - ArrayList elements + ArrayList elements, + ArrayList fields ) { this.type = type.type; this.text = text; this.elements = elements; + this.fields = fields; } /* { diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java index b7a2e875..a8c1e279 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java @@ -27,6 +27,7 @@ public class SlackBotUtilTest { public void testGetReviewerMessage_ActionEnabled() { jitApproval.setAction(JitRequestStatus.PENDING); jitApproval.setId(1L); + jitRequest.setId(1L); SlackBotAttachment result = slackBotUtil.getReviewerDm(userEmail, jitRequest, jitApproval, true, SlackColor.INFO); @@ -47,6 +48,7 @@ public class SlackBotUtilTest { @Test public void testGroupMessage() { + jitRequest.setId(1L); SlackBotAttachment result = slackBotUtil.getChannelMessage(jitRequest, userEmail, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), SlackColor.INFO); From 0cfcc76d9005e03fbb8e388bf1dab0e2748d02d2 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Tue, 16 Apr 2024 22:27:21 +0530 Subject: [PATCH 057/108] INFRA-2220 | Harinder | Updating query in JitRequestsRepository to use BETWEEN operator for better readability --- .../infra/portal/v2/jit/repository/JitRequestsRepository.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java index 6dd8f5cf..a38d31d1 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitRequestsRepository.java @@ -13,8 +13,7 @@ public interface JitRequestsRepository extends JpaRepository { @Query(value = "SELECT * FROM jit_requests WHERE requested_for_id = :requestedForId " + "AND resource_type = :resourceType AND environment = :env " + "AND resource_action = :resourceAction " - + "AND grant_at <= :grantAt " - + "AND grant_at + interval '1 hour' * grant_window >= :grantAt " + + "AND :grantAt BETWEEN grant_at AND grant_at + interval '1 hour' * grant_window " + "AND status='PENDING'", nativeQuery = true) List findDuplicateRequestsByUser( From ab214a611cc9d4500435227f94a450ebeac02fe2 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 17 Apr 2024 16:55:24 +0530 Subject: [PATCH 058/108] INFRA-3105 | Dhruv | initial commit for export manifest api --- .../portal/controller/ManifestController.java | 11 +- .../service/manifest/ManifestService.java | 24 ++- .../portal/util/JsonTransformationUtils.java | 38 +++++ .../ManifestServiceIntegrationTest.java | 41 ++++- .../util/JsonTransformationUtilTest.java | 49 ++++++ ...s-removal-with-no-super-secret-access.json | 141 ++++++++++++++++ ...st-keys-removal-without-secret-access.json | 141 ++++++++++++++++ ...manifest-keys-removal-redacted-secret.json | 151 ++++++++++++++++++ .../manifest/manifest-keys-removal.json | 151 ++++++++++++++++++ 9 files changed, 726 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/navi/infra/portal/util/JsonTransformationUtils.java create mode 100644 src/test/java/com/navi/infra/portal/util/JsonTransformationUtilTest.java create mode 100644 src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-with-no-super-secret-access.json create mode 100644 src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-without-secret-access.json create mode 100644 src/test/resources/fixtures/manifest/manifest-keys-removal-redacted-secret.json create mode 100644 src/test/resources/fixtures/manifest/manifest-keys-removal.json diff --git a/src/main/java/com/navi/infra/portal/controller/ManifestController.java b/src/main/java/com/navi/infra/portal/controller/ManifestController.java index f9eca45c..7b9273c4 100644 --- a/src/main/java/com/navi/infra/portal/controller/ManifestController.java +++ b/src/main/java/com/navi/infra/portal/controller/ManifestController.java @@ -6,12 +6,10 @@ import static org.springframework.http.HttpStatus.FORBIDDEN; import com.navi.infra.portal.domain.manifest.Manifest; import com.navi.infra.portal.domain.manifest.ManifestAudit; import com.navi.infra.portal.dto.manifest.CloneManifestRequest; -import com.navi.infra.portal.v2.grafanadashboard.dto.CreateDashboardRequest; -import com.navi.infra.portal.v2.grafanadashboard.dto.GrafanaDashboardResponse; import com.navi.infra.portal.dto.manifest.ManifestResponse; import com.navi.infra.portal.repository.ManifestName; import com.navi.infra.portal.service.manifest.ManifestService; -import com.navi.infra.portal.v2.grafanadashboard.entity.GrafanaDashboard; +import com.navi.infra.portal.v2.grafanadashboard.dto.GrafanaDashboardResponse; import com.navi.infra.portal.v2.grafanadashboard.service.GrafanaDashboardService; import com.navi.infra.portal.v2.manifest.dto.DeploymentStatusRequestDto; import java.util.List; @@ -82,6 +80,11 @@ public class ManifestController { return manifestService.fetchById(id); } + @GetMapping("/{id}/export") + public Manifest exportManifest(@PathVariable Long id) { + return manifestService.exportManifestById(id); + } + @GetMapping("/env/{environment}/name/{name}/kube") public String fetchKubeObjectByName( @PathVariable String name, @PathVariable String environment, @@ -158,5 +161,5 @@ public class ManifestController { ) { return grafanaDashboardService.findGrafanaDashboardByManifest(id); } - + } diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index ff036b13..932d09d2 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -5,6 +5,8 @@ import static com.navi.infra.portal.constants.LoadBalancerParent.FLINK; import static com.navi.infra.portal.domain.manifest.Manifest.redactedEmptyValueString; import static com.navi.infra.portal.domain.manifest.Manifest.redactedValueString; import static com.navi.infra.portal.util.FlatMapUtil.flatten; +import static com.navi.infra.portal.util.JsonTransformationUtils.removeKey; +import static com.navi.infra.portal.util.Mapper.mapper; import static com.navi.infra.portal.v2.privilege.Action.KUBE_DELETE; import static com.navi.infra.portal.v2.privilege.Action.MANIFEST_DELETE; import static com.navi.infra.portal.v2.privilege.Action.MANIFEST_READ; @@ -72,34 +74,20 @@ import org.springframework.transaction.annotation.Transactional; public class ManifestService { private final ObjectMapper objectMapper; - private final ManifestRepository manifestRepository; - private final ManifestAuditRepository manifestAuditRepository; - private final ValidationUtils manifestValidationUtil; - private final VaultService vaultService; - private final KubernetesManifestService kubernetesManifestService; - private final PortalEventPublisher portalEventPublisher; - private final PrivilegeUtilService privilegeUtilService; - private final ManifestAuditService manifestAuditService; - private final UserService userService; - private final MapDiffUtil mapDiffUtil; - private final AuthorizationService authorizationFilter; - private final LoadBalancerService loadBalancerService; - private final List extraResourceList; - ManifestService( ObjectMapper objectMapper, ManifestRepository manifestRepository, @@ -764,5 +752,13 @@ public class ManifestService { return manifestRepository.findManifestNameById(id); } + public Manifest exportManifestById(Long id) { + final Set keysToExclude = Set.of("version", "id", "isDeployed"); + var manifest = this.fetchById(id); + Map manifestAsMap = mapper.convertValue(manifest, Map.class); + removeKey(manifestAsMap, keysToExclude); + Manifest transformedManifest = mapper.convertValue(manifestAsMap, Manifest.class); + return transformedManifest; + } } diff --git a/src/main/java/com/navi/infra/portal/util/JsonTransformationUtils.java b/src/main/java/com/navi/infra/portal/util/JsonTransformationUtils.java new file mode 100644 index 00000000..2f7edf9d --- /dev/null +++ b/src/main/java/com/navi/infra/portal/util/JsonTransformationUtils.java @@ -0,0 +1,38 @@ +package com.navi.infra.portal.util; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +public final class JsonTransformationUtils { + + private JsonTransformationUtils() { + throw new AssertionError("No instances for you!"); + } + + @SuppressWarnings("unchecked") + public static void removeKey(Map data, Set keys) { + var iterator = data.entrySet().iterator(); + while (iterator.hasNext()) { + var entry = iterator.next(); + if (keys.contains(entry.getKey())) { + iterator.remove(); + } else if (entry.getValue() instanceof Map) { + removeKey((Map) entry.getValue(), keys); + } else if (entry.getValue() instanceof List) { + removeKey((List) entry.getValue(), keys); + } + } + } + + @SuppressWarnings("unchecked") + public static void removeKey(List data, Set keys) { + for (Object item : data) { + if (item instanceof Map) { + removeKey((Map) item, keys); + } else if (item instanceof List) { + removeKey((List) item, keys); + } + } + } +} diff --git a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java index 42812d77..6749efd4 100644 --- a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java +++ b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java @@ -2,7 +2,6 @@ package com.navi.infra.portal.service; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; import com.fasterxml.jackson.databind.ObjectMapper; @@ -10,7 +9,6 @@ import com.navi.infra.portal.domain.manifest.Manifest; import com.navi.infra.portal.domain.manifest.ManifestAudit; import com.navi.infra.portal.dto.manifest.ManifestResponse; import com.navi.infra.portal.exceptions.DuplicateLoadBalancerEndpointException; -import com.navi.infra.portal.exceptions.KubernetesManifestException; import com.navi.infra.portal.provider.ExternalIntegrationProvider; import com.navi.infra.portal.service.manifest.ManifestService; import java.io.IOException; @@ -230,7 +228,7 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider @Test @WithMockUser(value = "admin_user", username = "admin@navi.com", authorities = { "manifest:Infra:dev:.*:secret_write", "manifest:Infra:dev:.*:secret_read", - "manifest:Infra:dev:.*:supersecret_write","manifest:Infra:dev:.*:supersecret_read", + "manifest:Infra:dev:.*:supersecret_write", "manifest:Infra:dev:.*:supersecret_read", "manifest:Infra:dev:.*:write", "manifest:Infra:dev:.*:substitute_secrets"}, password = "admin") @DisplayName("Test Manifest Audit Create") @@ -275,4 +273,41 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider assertEquals(expected, actual, false); } + + @Test + @WithMockUser(value = "read_user", username = "admin@navi.com", authorities = { + "manifest:Infra:dev:.*:secret_write", "manifest:Infra:dev:.*:secret_read", + "manifest:Infra:dev:.*:supersecret_write", "manifest:Infra:dev:.*:read", + "manifest:Infra:dev:.*:write"}, password = "read") + @Transactional + @DisplayName("Export Manifest Without any super secret access") + void ExportManifestWithoutSuperSecretAccessTest() throws IOException { + Manifest manifestRequest = readFileToManifest("fixtures/manifest/" + + "manifest-keys-removal.json"); + String expectedManifestGetOutputJson = readFile("fixtures/manifest/expected_output/" + + "manifest-keys-removal-with-no-super-secret-access.json"); + manifestService.createOrUpdate(manifestRequest); + Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("test-export", "dev"); + + Manifest transformedManifest = manifestService.exportManifestById(fetchManifest.getId()); + String actualManifestJson = transformedManifest.convertToString(); + assertAll(() -> assertEquals(expectedManifestGetOutputJson, actualManifestJson, false)); + } + + @Test + @WithMockUser(value = "read_user", username = "admin@navi.com", authorities = { + "manifest:Infra:dev:.*:read"}, password = "read") + @Transactional + @DisplayName("Export Manifest Without any secret access") + void ExportManifestWithoutAnySecretAccessTest() throws IOException { + Manifest manifestRequest = readFileToManifest("fixtures/manifest/" + + "manifest-keys-removal-redacted-secret.json"); + String expectedManifestGetOutputJson = readFile("fixtures/manifest/expected_output/" + + "manifest-keys-removal-without-secret-access.json"); + testEntityManager.merge(manifestRequest); + Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("test-export", "dev"); + Manifest transformedManifest = manifestService.exportManifestById(fetchManifest.getId()); + String actualManifestJson = transformedManifest.convertToString(); + assertAll(() -> assertEquals(expectedManifestGetOutputJson, actualManifestJson, false)); + } } diff --git a/src/test/java/com/navi/infra/portal/util/JsonTransformationUtilTest.java b/src/test/java/com/navi/infra/portal/util/JsonTransformationUtilTest.java new file mode 100644 index 00000000..a71a2c9d --- /dev/null +++ b/src/test/java/com/navi/infra/portal/util/JsonTransformationUtilTest.java @@ -0,0 +1,49 @@ +package com.navi.infra.portal.util; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class JsonTransformationUtilTest { + + @Test + @DisplayName("should delete keys from object") + void shouldDeleteKeys() { + Map map = new HashMap<>(Map.of("test", new ArrayList<>(List.of( + new HashMap<>(Map.of("key1", "1", "key3", "test1")), + new HashMap<>(Map.of("key2", "2", "key4", "test2")) + )), + "key3", "2", "key2", "3", "key4", "4" + )); + var expected = new HashMap<>( + Map.of("test", new ArrayList<>(List.of(Map.of(), + Map.of("key4", "test2") + )), + "key4", "4")); + var keysToRemove = Set.of("key1", "key2", "key3"); + JsonTransformationUtils.removeKey(map, keysToRemove); + assertEquals(expected, map); + } + + @Test + @DisplayName("should process empty and null object") + void shouldProcessNullAndEmpty() { + Map map1 = new HashMap<>(); + Map map2 = new HashMap(); + map2.put("key", null); + var expected1 = new HashMap<>(Map.of()); + var expected2 = new HashMap(); + expected2.put("key", null); + var keysToRemove = Set.of("key1", "key2", "key3"); + JsonTransformationUtils.removeKey(map1, keysToRemove); + JsonTransformationUtils.removeKey(map2, keysToRemove); + assertEquals(expected1, map1); + assertEquals(expected2, map2); + } +} diff --git a/src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-with-no-super-secret-access.json b/src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-with-no-super-secret-access.json new file mode 100644 index 00000000..6af93871 --- /dev/null +++ b/src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-with-no-super-secret-access.json @@ -0,0 +1,141 @@ +{ + "environmentVariables": [ + { + "name": "APP_NAME", + "type": "CONFIG", + "sha256": "1b4f0e9851971998e732078544c96b36c3d01cedf7caa332359d6f1d83567014", + "value": "test1" + }, + { + "name": "test_Config", + "type": "SECRET", + "sha256": "60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752", + "value": "test2" + }, + { + "name": "test_super_secret", + "type": "SUPER_SECRET", + "sha256": "ddfaa92ae32b9ff82c40ce5e3350f16de528f021727f13468d9b26201905f59a", + "value": "*****" + } + ], + "metadata": { + "repo": "test", + "language": "Java", + "product": "lending", + "dataSensitivity": "PII_SPI", + "logCriticality": "AccessLogs", + "disasterRecovery": "True" + }, + "deployment": { + "loadBalancers": [ + { + "endpoint": "test-app1.spike.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "endpoint": "test-app2.spike.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "endpoint": "dev-test.spike.navi-tech.in", + "extraSecurityGroups": [ + "testapp-sg-1" + ], + "accessPolicies": [ + "internetFacing" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + } + ], + "alerts": { + "elb4xx": { + "duration": "3m", + "severity": "critical", + "threshold": 1 + }, + "elb5xx": { + "duration": "3m", + "severity": "critical", + "threshold": 1 + }, + "http4xx": { + "duration": "3m", + "severity": "critical", + "threshold": 15 + }, + "http5xx": { + "duration": "3m", + "severity": "critical", + "threshold": 2 + }, + "latency": { + "duration": "3m", + "severity": "warning", + "threshold": 800 + }, + "prometheusRecordingRule": [] + }, + "instance": { + "cpu": 0.24, + "memory": "300Mi" + }, + "exposedPorts": [ + { + "name": "serviceport", + "port": 8080 + }, + { + "name": "metrics", + "port": 4001 + } + ], + "allowEgress": [], + "healthCheck": { + "livenessCheck": { + "path": "/actuator/health", + "port": "metrics", + "type": "http", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + }, + "readinessCheck": { + "port": "serviceport", + "type": "tcp", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + } + }, + "hpa": { + "maxReplicas": 2, + "minReplicas": 2 + }, + "timeout": 1500, + "namespace": "dev" + }, + "team": { + "name": "Infra" + }, + "labels": { + "micrometer-prometheus": "enabled" + }, + "environment": "dev", + "name": "test-export", + "cluster": "spike.np.navi-tech.in" +} \ No newline at end of file diff --git a/src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-without-secret-access.json b/src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-without-secret-access.json new file mode 100644 index 00000000..74b97d95 --- /dev/null +++ b/src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-without-secret-access.json @@ -0,0 +1,141 @@ +{ + "environmentVariables": [ + { + "name": "APP_NAME", + "type": "CONFIG", + "sha256": "1b4f0e9851971998e732078544c96b36c3d01cedf7caa332359d6f1d83567014", + "value": "test1" + }, + { + "name": "test_Config", + "type": "SECRET", + "sha256": "60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752", + "value": "*****" + }, + { + "name": "test_super_secret", + "type": "SUPER_SECRET", + "sha256": "ddfaa92ae32b9ff82c40ce5e3350f16de528f021727f13468d9b26201905f59a", + "value": "*****" + } + ], + "metadata": { + "repo": "test", + "language": "Java", + "product": "lending", + "dataSensitivity": "PII_SPI", + "logCriticality": "AccessLogs", + "disasterRecovery": "True" + }, + "deployment": { + "loadBalancers": [ + { + "endpoint": "test-app1.spike.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "endpoint": "test-app2.spike.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "endpoint": "dev-test.spike.navi-tech.in", + "extraSecurityGroups": [ + "testapp-sg-1" + ], + "accessPolicies": [ + "internetFacing" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + } + ], + "alerts": { + "elb4xx": { + "duration": "3m", + "severity": "critical", + "threshold": 1 + }, + "elb5xx": { + "duration": "3m", + "severity": "critical", + "threshold": 1 + }, + "http4xx": { + "duration": "3m", + "severity": "critical", + "threshold": 15 + }, + "http5xx": { + "duration": "3m", + "severity": "critical", + "threshold": 2 + }, + "latency": { + "duration": "3m", + "severity": "warning", + "threshold": 800 + }, + "prometheusRecordingRule": [] + }, + "instance": { + "cpu": 0.24, + "memory": "300Mi" + }, + "exposedPorts": [ + { + "name": "serviceport", + "port": 8080 + }, + { + "name": "metrics", + "port": 4001 + } + ], + "allowEgress": [], + "healthCheck": { + "livenessCheck": { + "path": "/actuator/health", + "port": "metrics", + "type": "http", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + }, + "readinessCheck": { + "port": "serviceport", + "type": "tcp", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + } + }, + "hpa": { + "maxReplicas": 2, + "minReplicas": 2 + }, + "timeout": 1500, + "namespace": "dev" + }, + "team": { + "name": "Infra" + }, + "labels": { + "micrometer-prometheus": "enabled" + }, + "environment": "dev", + "name": "test-export", + "cluster": "spike.np.navi-tech.in" +} \ No newline at end of file diff --git a/src/test/resources/fixtures/manifest/manifest-keys-removal-redacted-secret.json b/src/test/resources/fixtures/manifest/manifest-keys-removal-redacted-secret.json new file mode 100644 index 00000000..68617379 --- /dev/null +++ b/src/test/resources/fixtures/manifest/manifest-keys-removal-redacted-secret.json @@ -0,0 +1,151 @@ +{ + "version": 46, + "environmentVariables": [ + { + "name": "APP_NAME", + "type": "CONFIG", + "sha256": "1b4f0e9851971998e732078544c96b36c3d01cedf7caa332359d6f1d83567014", + "value": "test1" + }, + { + "name": "test_Config", + "type": "SECRET", + "sha256": "60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752", + "value": null + }, + { + "name": "test_super_secret", + "type": "SUPER_SECRET", + "sha256": "ddfaa92ae32b9ff82c40ce5e3350f16de528f021727f13468d9b26201905f59a", + "value": null + } + ], + "metadata": { + "repo": "test", + "language": "Java", + "product": "lending", + "dataSensitivity": "PII_SPI", + "logCriticality": "AccessLogs", + "disasterRecovery": "True" + }, + "deployment": { + "id": 1, + "version": 22, + "loadBalancers": [ + { + "version": 3, + "id": 22, + "endpoint": "test-app1.spike.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "version": 23, + "id": 34, + "endpoint": "test-app2.spike.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "version": 23, + "id": 72, + "endpoint": "dev-test.spike.navi-tech.in", + "extraSecurityGroups": [ + "testapp-sg-1" + ], + "accessPolicies": [ + "internetFacing" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + } + ], + "alerts": { + "elb4xx": { + "duration": "3m", + "severity": "critical", + "threshold": 1 + }, + "elb5xx": { + "duration": "3m", + "severity": "critical", + "threshold": 1 + }, + "http4xx": { + "duration": "3m", + "severity": "critical", + "threshold": 15 + }, + "http5xx": { + "duration": "3m", + "severity": "critical", + "threshold": 2 + }, + "latency": { + "duration": "3m", + "severity": "warning", + "threshold": 800 + }, + "prometheusRecordingRule": [] + }, + "instance": { + "cpu": 0.24, + "memory": "300Mi" + }, + "exposedPorts": [ + { + "name": "serviceport", + "port": 8080 + }, + { + "name": "metrics", + "port": 4001 + } + ], + "allowEgress": [], + "healthCheck": { + "livenessCheck": { + "path": "/actuator/health", + "port": "metrics", + "type": "http", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + }, + "readinessCheck": { + "port": "serviceport", + "type": "tcp", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + } + }, + "hpa": { + "maxReplicas": 2, + "minReplicas": 2 + }, + "timeout": 1500, + "namespace": "dev" + }, + "team": { + "name": "Infra" + }, + "labels": { + "micrometer-prometheus": "enabled" + }, + "environment": "dev", + "name": "test-export", + "cluster": "spike.np.navi-tech.in", + "isDeployed": true +} \ No newline at end of file diff --git a/src/test/resources/fixtures/manifest/manifest-keys-removal.json b/src/test/resources/fixtures/manifest/manifest-keys-removal.json new file mode 100644 index 00000000..2d4b7d0c --- /dev/null +++ b/src/test/resources/fixtures/manifest/manifest-keys-removal.json @@ -0,0 +1,151 @@ +{ + "version": 46, + "environmentVariables": [ + { + "name": "APP_NAME", + "type": "CONFIG", + "sha256": "1b4f0e9851971998e732078544c96b36c3d01cedf7caa332359d6f1d83567014", + "value": "test1" + }, + { + "name": "test_Config", + "type": "SECRET", + "sha256": "60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752", + "value": "test2" + }, + { + "name": "test_super_secret", + "type": "SUPER_SECRET", + "sha256": "ddfaa92ae32b9ff82c40ce5e3350f16de528f021727f13468d9b26201905f59a", + "value": "*****" + } + ], + "metadata": { + "repo": "test", + "language": "Java", + "product": "lending", + "dataSensitivity": "PII_SPI", + "logCriticality": "AccessLogs", + "disasterRecovery": "True" + }, + "deployment": { + "id": 1, + "version": 22, + "loadBalancers": [ + { + "version": 3, + "id": 22, + "endpoint": "test-app1.spike.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "version": 23, + "id": 34, + "endpoint": "test-app2.spike.navi-tech.in", + "accessPolicies": [ + "internal" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + }, + { + "version": 23, + "id": 72, + "endpoint": "dev-test.spike.navi-tech.in", + "extraSecurityGroups": [ + "testapp-sg-1" + ], + "accessPolicies": [ + "internetFacing" + ], + "stickiness": false, + "idleTimeout": 60, + "type": "alb" + } + ], + "alerts": { + "elb4xx": { + "duration": "3m", + "severity": "critical", + "threshold": 1 + }, + "elb5xx": { + "duration": "3m", + "severity": "critical", + "threshold": 1 + }, + "http4xx": { + "duration": "3m", + "severity": "critical", + "threshold": 15 + }, + "http5xx": { + "duration": "3m", + "severity": "critical", + "threshold": 2 + }, + "latency": { + "duration": "3m", + "severity": "warning", + "threshold": 800 + }, + "prometheusRecordingRule": [] + }, + "instance": { + "cpu": 0.24, + "memory": "300Mi" + }, + "exposedPorts": [ + { + "name": "serviceport", + "port": 8080 + }, + { + "name": "metrics", + "port": 4001 + } + ], + "allowEgress": [], + "healthCheck": { + "livenessCheck": { + "path": "/actuator/health", + "port": "metrics", + "type": "http", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + }, + "readinessCheck": { + "port": "serviceport", + "type": "tcp", + "periodSeconds": 30, + "failureThreshold": 5, + "successThreshold": 1, + "initialDelaySeconds": 60 + } + }, + "hpa": { + "maxReplicas": 2, + "minReplicas": 2 + }, + "timeout": 1500, + "namespace": "dev" + }, + "team": { + "name": "Infra" + }, + "labels": { + "micrometer-prometheus": "enabled" + }, + "environment": "dev", + "name": "test-export", + "cluster": "spike.np.navi-tech.in", + "isDeployed": true +} \ No newline at end of file From ac4c82a845cc76c94d64c5488a09599f1998bc90 Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Wed, 17 Apr 2024 17:14:02 +0530 Subject: [PATCH 059/108] INFRA-809 | Ashvin | Fix group name 63 char limit (#892) If group name exceeds 63 char limit then we will create sha of the propsed name with first 10 characters of the original name to help identify the name of the service Related PR: https://github.com/navi-infra/kutegen/pull/14 --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index ee17d557..088b3091 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit ee17d5576b4105e69d9001685f32af7787879ad7 +Subproject commit 088b3091dd59ded1dd558229418ff8929df0f42a From 5eeb271d8d5edb75c73d834ecd2ce35d34929f51 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 17 Apr 2024 17:34:30 +0530 Subject: [PATCH 060/108] INFRA-3149 | Dhruv | py script to migrate amc manifest --- kutegen | 2 +- scripts/amc_manifest_migration.py | 64 +++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 scripts/amc_manifest_migration.py diff --git a/kutegen b/kutegen index 088b3091..671c84b2 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 088b3091dd59ded1dd558229418ff8929df0f42a +Subproject commit 671c84b2022cd6071a1942cdad1803135ce2b443 diff --git a/scripts/amc_manifest_migration.py b/scripts/amc_manifest_migration.py new file mode 100644 index 00000000..76193906 --- /dev/null +++ b/scripts/amc_manifest_migration.py @@ -0,0 +1,64 @@ +#!/usr/bin/python3 + +import requests + +url_to_fetch = "" # FILL ME +url_to_post = "" # FILL ME +get_cookie = "" # FILL ME +get_x_xsrf_token = "" # FILL ME +post_cookie = "" # FILL ME +post_x_xsrf_token = "" # FILL ME +get_manifest = requests.Session() +get_manifest.headers.update({'cookie': get_cookie, 'x-xsrf-token': get_x_xsrf_token}) +post_manifest = requests.Session() +post_manifest.headers.update({'cookie': post_cookie, 'x-xsrf-token': post_x_xsrf_token}) + +ids = [] # FILL ME + + +def remove_version_id_keys(data): + if isinstance(data, dict): + return {key: remove_version_id_keys(value) for key, value in data.items() if + key not in ['version', 'id']} + elif isinstance(data, list): + return [remove_version_id_keys(item) for item in data] + else: + return data + + +def replace_key(data, key_to_replace, value_to_replace, replace_with): + if isinstance(data, dict): + return { + key: replace_key(value, key_to_replace, value_to_replace, replace_with) if isinstance( + value, (dict, list)) + else ( + value.replace(value_to_replace, replace_with) if isinstance(value, + str) and key == key_to_replace + else replace_with if value == value_to_replace and key == key_to_replace and isinstance( + value, type(value_to_replace)) + else value + ) + for key, value in data.items() + } + elif isinstance(data, list): + return [replace_key(item, key_to_replace, value_to_replace, replace_with) for item in data] + else: + return data + + +replacements = [ + ('product', 'lending', 'amc'), + ('infraVertical', 'lending', 'amc'), + ('cluster', 'nonprod.np.navi-tech.in', 'aps1.np.navi-amc.in'), + ('endpoint', 'np.navi-tech.in', 'np.navi-amc.in'), + ('isDeployed', True, False) +] + +for id in ids: + r = get_manifest.get(url_to_fetch + id) + get_manifest_response = r.json() + manifest_data_to_post = remove_version_id_keys(get_manifest_response) + for key, old_value, new_value in replacements: + manifest_data_to_post = replace_key(manifest_data_to_post, key, old_value, new_value) + post_manifest_response = post_manifest.post(f"{url_to_post}", json=manifest_data_to_post) + print(f'manifestId:{id} status code {post_manifest_response.status_code}') From fefb655c5e5f7ccccb985da409876c6d96aef68f Mon Sep 17 00:00:00 2001 From: Saqib Perwaiz Date: Wed, 17 Apr 2024 20:08:00 +0530 Subject: [PATCH 061/108] INFRA-3162 | Saqib | Change service account file name --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 088b3091..f7140b0f 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 088b3091dd59ded1dd558229418ff8929df0f42a +Subproject commit f7140b0f07690412704b7ed0314cc4ac982f79ab From 3934bfe51a4ea0fd9bc5c015e70a8bf2e4a867c1 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Thu, 18 Apr 2024 13:33:18 +0530 Subject: [PATCH 062/108] INFRA-3105 | Dhruv | add replace function in object transformation util and code cleanup --- .../service/manifest/ManifestService.java | 7 +- .../portal/util/JsonTransformationUtils.java | 38 ------- .../portal/util/ObjectTransformationUtil.java | 75 ++++++++++++++ .../ManifestServiceIntegrationTest.java | 24 ++--- .../util/JsonTransformationUtilTest.java | 49 ---------- .../util/ObjectTransformationUtilTest.java | 98 +++++++++++++++++++ ...t-export-with-no-super-secret-access.json} | 4 +- ...anifest-export-without-secret-access.json} | 4 +- ...n => manifest-export-redacted-secret.json} | 1 + ...keys-removal.json => manifest-export.json} | 1 + 10 files changed, 197 insertions(+), 104 deletions(-) delete mode 100644 src/main/java/com/navi/infra/portal/util/JsonTransformationUtils.java create mode 100644 src/main/java/com/navi/infra/portal/util/ObjectTransformationUtil.java delete mode 100644 src/test/java/com/navi/infra/portal/util/JsonTransformationUtilTest.java create mode 100644 src/test/java/com/navi/infra/portal/util/ObjectTransformationUtilTest.java rename src/test/resources/fixtures/manifest/expected_output/{manifest-keys-removal-with-no-super-secret-access.json => manifest-export-with-no-super-secret-access.json} (97%) rename src/test/resources/fixtures/manifest/expected_output/{manifest-keys-removal-without-secret-access.json => manifest-export-without-secret-access.json} (97%) rename src/test/resources/fixtures/manifest/{manifest-keys-removal-redacted-secret.json => manifest-export-redacted-secret.json} (99%) rename src/test/resources/fixtures/manifest/{manifest-keys-removal.json => manifest-export.json} (99%) diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index 932d09d2..6c9c8720 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -5,7 +5,6 @@ import static com.navi.infra.portal.constants.LoadBalancerParent.FLINK; import static com.navi.infra.portal.domain.manifest.Manifest.redactedEmptyValueString; import static com.navi.infra.portal.domain.manifest.Manifest.redactedValueString; import static com.navi.infra.portal.util.FlatMapUtil.flatten; -import static com.navi.infra.portal.util.JsonTransformationUtils.removeKey; import static com.navi.infra.portal.util.Mapper.mapper; import static com.navi.infra.portal.v2.privilege.Action.KUBE_DELETE; import static com.navi.infra.portal.v2.privilege.Action.MANIFEST_DELETE; @@ -41,6 +40,7 @@ import com.navi.infra.portal.service.kubernetes.KubernetesManifestService; import com.navi.infra.portal.service.user.PrivilegeUtilService; import com.navi.infra.portal.service.user.UserService; import com.navi.infra.portal.util.MapDiffUtil; +import com.navi.infra.portal.util.ObjectTransformationUtil; import com.navi.infra.portal.util.manifest.ValidationUtils; import com.navi.infra.portal.v2.loadbalancer.FindGroupNameRequest; import com.navi.infra.portal.v2.loadbalancer.LoadBalancerService; @@ -753,10 +753,11 @@ public class ManifestService { } public Manifest exportManifestById(Long id) { - final Set keysToExclude = Set.of("version", "id", "isDeployed"); + final Set keysToExclude = Set.of("version", "id"); var manifest = this.fetchById(id); Map manifestAsMap = mapper.convertValue(manifest, Map.class); - removeKey(manifestAsMap, keysToExclude); + ObjectTransformationUtil.removeKeys(manifestAsMap, keysToExclude); + ObjectTransformationUtil.replaceKeys(manifestAsMap, Map.of("isDeployed", false)); Manifest transformedManifest = mapper.convertValue(manifestAsMap, Manifest.class); return transformedManifest; } diff --git a/src/main/java/com/navi/infra/portal/util/JsonTransformationUtils.java b/src/main/java/com/navi/infra/portal/util/JsonTransformationUtils.java deleted file mode 100644 index 2f7edf9d..00000000 --- a/src/main/java/com/navi/infra/portal/util/JsonTransformationUtils.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.navi.infra.portal.util; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -public final class JsonTransformationUtils { - - private JsonTransformationUtils() { - throw new AssertionError("No instances for you!"); - } - - @SuppressWarnings("unchecked") - public static void removeKey(Map data, Set keys) { - var iterator = data.entrySet().iterator(); - while (iterator.hasNext()) { - var entry = iterator.next(); - if (keys.contains(entry.getKey())) { - iterator.remove(); - } else if (entry.getValue() instanceof Map) { - removeKey((Map) entry.getValue(), keys); - } else if (entry.getValue() instanceof List) { - removeKey((List) entry.getValue(), keys); - } - } - } - - @SuppressWarnings("unchecked") - public static void removeKey(List data, Set keys) { - for (Object item : data) { - if (item instanceof Map) { - removeKey((Map) item, keys); - } else if (item instanceof List) { - removeKey((List) item, keys); - } - } - } -} diff --git a/src/main/java/com/navi/infra/portal/util/ObjectTransformationUtil.java b/src/main/java/com/navi/infra/portal/util/ObjectTransformationUtil.java new file mode 100644 index 00000000..46545d16 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/util/ObjectTransformationUtil.java @@ -0,0 +1,75 @@ +package com.navi.infra.portal.util; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +public final class ObjectTransformationUtil { + + private ObjectTransformationUtil() { + throw new AssertionError("No instances for you!"); + } + + @SuppressWarnings("unchecked") + public static void removeKeys(Map data, Set keys) { + var iterator = data.entrySet().iterator(); + while (iterator.hasNext()) { + var entry = iterator.next(); + if (keys.contains(entry.getKey())) { + iterator.remove(); + } else if (entry.getValue() instanceof Map) { + removeKeys((Map) entry.getValue(), keys); + } else if (entry.getValue() instanceof List) { + removeKeys((List) entry.getValue(), keys); + } + } + } + + @SuppressWarnings("unchecked") + public static void removeKeys(List data, Set keys) { + for (Object item : data) { + if (item instanceof Map) { + removeKeys((Map) item, keys); + } else if (item instanceof List) { + removeKeys((List) item, keys); + } + } + } + + @SuppressWarnings("unchecked") + public static void replaceKeys( + Map data, + Map replacements + ) { + for (Map.Entry entry : data.entrySet()) { + if (replacements.containsKey(entry.getKey())) { + entry.setValue(replacements.get(entry.getKey())); + } else if (entry.getValue() instanceof Map) { + replaceKeys((Map) entry.getValue(), replacements); + } else if (entry.getValue() instanceof List) { + for (Object item : (List) entry.getValue()) { + if (item instanceof Map) { + replaceKeys((Map) item, replacements); + } else if (item instanceof List) { + replaceKeys((List) item, replacements); + } + } + } + } + } + + + @SuppressWarnings("unchecked") + public static void replaceKeys( + List data, + Map replacements + ) { + for (Object item : data) { + if (item instanceof Map) { + replaceKeys((Map) item, replacements); + } else if (item instanceof List) { + replaceKeys((List) item, replacements); + } + } + } +} diff --git a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java index 6749efd4..14a8aed4 100644 --- a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java +++ b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java @@ -280,12 +280,12 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider "manifest:Infra:dev:.*:supersecret_write", "manifest:Infra:dev:.*:read", "manifest:Infra:dev:.*:write"}, password = "read") @Transactional - @DisplayName("Export Manifest Without any super secret access") - void ExportManifestWithoutSuperSecretAccessTest() throws IOException { - Manifest manifestRequest = readFileToManifest("fixtures/manifest/" + - "manifest-keys-removal.json"); - String expectedManifestGetOutputJson = readFile("fixtures/manifest/expected_output/" + - "manifest-keys-removal-with-no-super-secret-access.json"); + @DisplayName("export manifest without any super secret access") + void exportManifestWithoutSuperSecretAccessTest() throws IOException { + Manifest manifestRequest = readFileToManifest("fixtures/manifest/" + + "manifest-export.json"); + String expectedManifestGetOutputJson = readFile("fixtures/manifest/expected_output/" + + "manifest-export-with-no-super-secret-access.json"); manifestService.createOrUpdate(manifestRequest); Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("test-export", "dev"); @@ -298,12 +298,12 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider @WithMockUser(value = "read_user", username = "admin@navi.com", authorities = { "manifest:Infra:dev:.*:read"}, password = "read") @Transactional - @DisplayName("Export Manifest Without any secret access") - void ExportManifestWithoutAnySecretAccessTest() throws IOException { - Manifest manifestRequest = readFileToManifest("fixtures/manifest/" + - "manifest-keys-removal-redacted-secret.json"); - String expectedManifestGetOutputJson = readFile("fixtures/manifest/expected_output/" + - "manifest-keys-removal-without-secret-access.json"); + @DisplayName("export manifest without any secret access") + void exportManifestWithoutAnySecretAccessTest() throws IOException { + Manifest manifestRequest = readFileToManifest("fixtures/manifest/" + + "manifest-export-redacted-secret.json"); + String expectedManifestGetOutputJson = readFile("fixtures/manifest/expected_output/" + + "manifest-export-without-secret-access.json"); testEntityManager.merge(manifestRequest); Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("test-export", "dev"); Manifest transformedManifest = manifestService.exportManifestById(fetchManifest.getId()); diff --git a/src/test/java/com/navi/infra/portal/util/JsonTransformationUtilTest.java b/src/test/java/com/navi/infra/portal/util/JsonTransformationUtilTest.java deleted file mode 100644 index a71a2c9d..00000000 --- a/src/test/java/com/navi/infra/portal/util/JsonTransformationUtilTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.navi.infra.portal.util; - -import static org.junit.Assert.assertEquals; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -public class JsonTransformationUtilTest { - - @Test - @DisplayName("should delete keys from object") - void shouldDeleteKeys() { - Map map = new HashMap<>(Map.of("test", new ArrayList<>(List.of( - new HashMap<>(Map.of("key1", "1", "key3", "test1")), - new HashMap<>(Map.of("key2", "2", "key4", "test2")) - )), - "key3", "2", "key2", "3", "key4", "4" - )); - var expected = new HashMap<>( - Map.of("test", new ArrayList<>(List.of(Map.of(), - Map.of("key4", "test2") - )), - "key4", "4")); - var keysToRemove = Set.of("key1", "key2", "key3"); - JsonTransformationUtils.removeKey(map, keysToRemove); - assertEquals(expected, map); - } - - @Test - @DisplayName("should process empty and null object") - void shouldProcessNullAndEmpty() { - Map map1 = new HashMap<>(); - Map map2 = new HashMap(); - map2.put("key", null); - var expected1 = new HashMap<>(Map.of()); - var expected2 = new HashMap(); - expected2.put("key", null); - var keysToRemove = Set.of("key1", "key2", "key3"); - JsonTransformationUtils.removeKey(map1, keysToRemove); - JsonTransformationUtils.removeKey(map2, keysToRemove); - assertEquals(expected1, map1); - assertEquals(expected2, map2); - } -} diff --git a/src/test/java/com/navi/infra/portal/util/ObjectTransformationUtilTest.java b/src/test/java/com/navi/infra/portal/util/ObjectTransformationUtilTest.java new file mode 100644 index 00000000..18b58fc9 --- /dev/null +++ b/src/test/java/com/navi/infra/portal/util/ObjectTransformationUtilTest.java @@ -0,0 +1,98 @@ +package com.navi.infra.portal.util; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class ObjectTransformationUtilTest { + + @Test + @DisplayName("should delete keys from object") + void shouldDeleteKeys() { + Map map = new HashMap<>(Map.of("test", new ArrayList<>(List.of( + new HashMap<>(Map.of("key1", "1", "key3", "test1")), + new HashMap<>(Map.of("key2", "2", "key4", "test2")) + )), + "key3", "2", "key2", "3", "key4", "4" + )); + + final var keysToRemove = Set.of("key1", "key2", "key3"); + final var expected = new HashMap<>( + Map.of("test", new ArrayList<>(List.of(Map.of(), + Map.of("key4", "test2") + )), + "key4", "4")); + + ObjectTransformationUtil.removeKeys(map, keysToRemove); + + assertEquals(expected, map); + } + + @Test + @DisplayName("should replace keys from object") + void shouldReplaceKeys() { + Map map = new HashMap<>(Map.of("test", new ArrayList<>(List.of( + new HashMap<>(Map.of("key1", "1", "key3", "test1")), + new HashMap<>(Map.of("key2", "2", "key4", "test2")) + )), + "key3", "2", "key2", "3", "key4", "4" + )); + + final Map replacements = new HashMap<>( + Map.of("key1", true, "key2", "new2", "key3", false)); + final var expected = new HashMap<>(Map.of("test", new ArrayList<>(List.of( + new HashMap<>(Map.of("key1", true, "key3", false)), + new HashMap<>(Map.of("key2", "new2", "key4", "test2")) + )), + "key3", false, "key2", "new2", "key4", "4" + )); + + ObjectTransformationUtil.replaceKeys(map, replacements); + + assertEquals(expected, map); + } + + @Test + @DisplayName("should process empty and null object on remove") + void shouldProcessNullAndEmptyOnRemove() { + Map map1 = new HashMap<>(); + Map map2 = new HashMap(); + map2.put("key", null); + + final var keysToRemove = Set.of("key1"); + final var expected1 = new HashMap<>(Map.of()); + final var expected2 = new HashMap(); + expected2.put("key", null); + + ObjectTransformationUtil.removeKeys(map1, keysToRemove); + ObjectTransformationUtil.removeKeys(map2, keysToRemove); + + assertEquals(expected1, map1); + assertEquals(expected2, map2); + } + + @Test + @DisplayName("should process empty and null object on replace") + void shouldProcessNullAndEmptyOnReplace() { + Map map1 = new HashMap<>(); + Map map2 = new HashMap(); + map2.put("key", null); + + final Map replacements = new HashMap<>(Map.of("key", true)); + final var expected1 = new HashMap<>(Map.of()); + final var expected2 = new HashMap(); + expected2.put("key", true); + + ObjectTransformationUtil.replaceKeys(map1, replacements); + ObjectTransformationUtil.replaceKeys(map2, replacements); + + assertEquals(expected1, map1); + assertEquals(expected2, map2); + } +} diff --git a/src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-with-no-super-secret-access.json b/src/test/resources/fixtures/manifest/expected_output/manifest-export-with-no-super-secret-access.json similarity index 97% rename from src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-with-no-super-secret-access.json rename to src/test/resources/fixtures/manifest/expected_output/manifest-export-with-no-super-secret-access.json index 6af93871..71c2e626 100644 --- a/src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-with-no-super-secret-access.json +++ b/src/test/resources/fixtures/manifest/expected_output/manifest-export-with-no-super-secret-access.json @@ -28,6 +28,7 @@ "disasterRecovery": "True" }, "deployment": { + "isDeployed": false, "loadBalancers": [ { "endpoint": "test-app1.spike.navi-tech.in", @@ -137,5 +138,6 @@ }, "environment": "dev", "name": "test-export", - "cluster": "spike.np.navi-tech.in" + "cluster": "spike.np.navi-tech.in", + "isDeployed": false } \ No newline at end of file diff --git a/src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-without-secret-access.json b/src/test/resources/fixtures/manifest/expected_output/manifest-export-without-secret-access.json similarity index 97% rename from src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-without-secret-access.json rename to src/test/resources/fixtures/manifest/expected_output/manifest-export-without-secret-access.json index 74b97d95..f39718ca 100644 --- a/src/test/resources/fixtures/manifest/expected_output/manifest-keys-removal-without-secret-access.json +++ b/src/test/resources/fixtures/manifest/expected_output/manifest-export-without-secret-access.json @@ -28,6 +28,7 @@ "disasterRecovery": "True" }, "deployment": { + "isDeployed": false, "loadBalancers": [ { "endpoint": "test-app1.spike.navi-tech.in", @@ -137,5 +138,6 @@ }, "environment": "dev", "name": "test-export", - "cluster": "spike.np.navi-tech.in" + "cluster": "spike.np.navi-tech.in", + "isDeployed": false } \ No newline at end of file diff --git a/src/test/resources/fixtures/manifest/manifest-keys-removal-redacted-secret.json b/src/test/resources/fixtures/manifest/manifest-export-redacted-secret.json similarity index 99% rename from src/test/resources/fixtures/manifest/manifest-keys-removal-redacted-secret.json rename to src/test/resources/fixtures/manifest/manifest-export-redacted-secret.json index 68617379..351e1df8 100644 --- a/src/test/resources/fixtures/manifest/manifest-keys-removal-redacted-secret.json +++ b/src/test/resources/fixtures/manifest/manifest-export-redacted-secret.json @@ -31,6 +31,7 @@ "deployment": { "id": 1, "version": 22, + "isDeployed": true, "loadBalancers": [ { "version": 3, diff --git a/src/test/resources/fixtures/manifest/manifest-keys-removal.json b/src/test/resources/fixtures/manifest/manifest-export.json similarity index 99% rename from src/test/resources/fixtures/manifest/manifest-keys-removal.json rename to src/test/resources/fixtures/manifest/manifest-export.json index 2d4b7d0c..37ba6e9d 100644 --- a/src/test/resources/fixtures/manifest/manifest-keys-removal.json +++ b/src/test/resources/fixtures/manifest/manifest-export.json @@ -31,6 +31,7 @@ "deployment": { "id": 1, "version": 22, + "isDeployed": true, "loadBalancers": [ { "version": 3, From f84fcc2602dbab585fe03f02f6314309ba45476b Mon Sep 17 00:00:00 2001 From: Ankit Bhardwaj Bhardwaj Date: Thu, 18 Apr 2024 15:04:29 +0530 Subject: [PATCH 063/108] INFRA-3113 | Ankit Bhardwaj | udpate kutegen for java-heap-dump credentials update (#896) --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 671c84b2..8eb85e2e 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 671c84b2022cd6071a1942cdad1803135ce2b443 +Subproject commit 8eb85e2e0de55f97f6342f8351aab0ebfea85395 From 2cd2ece32aeff01598315dd0f136b2d60d2a2769 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Thu, 18 Apr 2024 15:52:11 +0530 Subject: [PATCH 064/108] INFRA-3105 | Dhruv | code cleanup --- .../portal/service/manifest/ManifestService.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index 6c9c8720..9ee14960 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -5,7 +5,6 @@ import static com.navi.infra.portal.constants.LoadBalancerParent.FLINK; import static com.navi.infra.portal.domain.manifest.Manifest.redactedEmptyValueString; import static com.navi.infra.portal.domain.manifest.Manifest.redactedValueString; import static com.navi.infra.portal.util.FlatMapUtil.flatten; -import static com.navi.infra.portal.util.Mapper.mapper; import static com.navi.infra.portal.v2.privilege.Action.KUBE_DELETE; import static com.navi.infra.portal.v2.privilege.Action.MANIFEST_DELETE; import static com.navi.infra.portal.v2.privilege.Action.MANIFEST_READ; @@ -754,12 +753,12 @@ public class ManifestService { public Manifest exportManifestById(Long id) { final Set keysToExclude = Set.of("version", "id"); - var manifest = this.fetchById(id); - Map manifestAsMap = mapper.convertValue(manifest, Map.class); + final Map keysToReplace = Map.of("isDeployed", false); + var manifest = fetchById(id); + Map manifestAsMap = objectMapper.convertValue(manifest, Map.class); ObjectTransformationUtil.removeKeys(manifestAsMap, keysToExclude); - ObjectTransformationUtil.replaceKeys(manifestAsMap, Map.of("isDeployed", false)); - Manifest transformedManifest = mapper.convertValue(manifestAsMap, Manifest.class); - return transformedManifest; + ObjectTransformationUtil.replaceKeys(manifestAsMap, keysToReplace); + return objectMapper.convertValue(manifestAsMap, Manifest.class); } } From 9aa21d3b9474c53ba32bd6876ec8d97813815be2 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Thu, 18 Apr 2024 17:40:13 +0530 Subject: [PATCH 065/108] INFRA-3105 | Dhruv | fix pr comments --- .../service/manifest/ManifestService.java | 2 +- .../util/ObjectTransformationUtilTest.java | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index 9ee14960..5aecea10 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -755,7 +755,7 @@ public class ManifestService { final Set keysToExclude = Set.of("version", "id"); final Map keysToReplace = Map.of("isDeployed", false); var manifest = fetchById(id); - Map manifestAsMap = objectMapper.convertValue(manifest, Map.class); + var manifestAsMap = manifest.convertToMap(); ObjectTransformationUtil.removeKeys(manifestAsMap, keysToExclude); ObjectTransformationUtil.replaceKeys(manifestAsMap, keysToReplace); return objectMapper.convertValue(manifestAsMap, Manifest.class); diff --git a/src/test/java/com/navi/infra/portal/util/ObjectTransformationUtilTest.java b/src/test/java/com/navi/infra/portal/util/ObjectTransformationUtilTest.java index 18b58fc9..282d93a2 100644 --- a/src/test/java/com/navi/infra/portal/util/ObjectTransformationUtilTest.java +++ b/src/test/java/com/navi/infra/portal/util/ObjectTransformationUtilTest.java @@ -1,6 +1,6 @@ package com.navi.infra.portal.util; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.HashMap; @@ -10,7 +10,7 @@ import java.util.Set; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -public class ObjectTransformationUtilTest { +class ObjectTransformationUtilTest { @Test @DisplayName("should delete keys from object") @@ -62,11 +62,11 @@ public class ObjectTransformationUtilTest { @DisplayName("should process empty and null object on remove") void shouldProcessNullAndEmptyOnRemove() { Map map1 = new HashMap<>(); - Map map2 = new HashMap(); + Map map2 = new HashMap<>(); map2.put("key", null); final var keysToRemove = Set.of("key1"); - final var expected1 = new HashMap<>(Map.of()); + final var expected1 = Map.of(); final var expected2 = new HashMap(); expected2.put("key", null); @@ -81,13 +81,12 @@ public class ObjectTransformationUtilTest { @DisplayName("should process empty and null object on replace") void shouldProcessNullAndEmptyOnReplace() { Map map1 = new HashMap<>(); - Map map2 = new HashMap(); + Map map2 = new HashMap<>(); map2.put("key", null); - final Map replacements = new HashMap<>(Map.of("key", true)); - final var expected1 = new HashMap<>(Map.of()); - final var expected2 = new HashMap(); - expected2.put("key", true); + final Map replacements = Map.of("key", true); + final var expected1 = Map.of(); + final var expected2 = Map.of("key", true); ObjectTransformationUtil.replaceKeys(map1, replacements); ObjectTransformationUtil.replaceKeys(map2, replacements); From 50e1e66d8eb9bd59e07942a4fc6c7a58d9a04b8c Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 18 Apr 2024 20:14:08 +0530 Subject: [PATCH 066/108] INFRA-3174 | Harinder | Updating default alert thresholds for elasticsearch --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 8eb85e2e..441b65f4 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 8eb85e2e0de55f97f6342f8351aab0ebfea85395 +Subproject commit 441b65f41408d90e2f6c0cb046b53f7fc1bd2537 From feeb8f2b7c301d9b677a0d1eeab41492d18d217f Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Mon, 22 Apr 2024 19:03:28 +0530 Subject: [PATCH 067/108] INFRA-809 | Ashvin | Fix missing flink jobs attributes (#899) --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 441b65f4..0b4f5548 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 441b65f41408d90e2f6c0cb046b53f7fc1bd2537 +Subproject commit 0b4f5548ad55a78754635af219218cebaade823f From 057008afd43b19a9715a3dfefcef8b5d0d492b89 Mon Sep 17 00:00:00 2001 From: Saqib Perwaiz Date: Tue, 23 Apr 2024 15:16:07 +0530 Subject: [PATCH 068/108] INFRA-3162 | Saqib | Remove allow_any policy from dev namespace --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 0b4f5548..128a158e 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 0b4f5548ad55a78754635af219218cebaade823f +Subproject commit 128a158e6b808d5adf225bdc72c5a99ec63448f9 From 313c8e141e9d261396ac74b2b4a0f58c4f6d6d13 Mon Sep 17 00:00:00 2001 From: Saqib Perwaiz Date: Tue, 23 Apr 2024 16:47:59 +0530 Subject: [PATCH 069/108] INFRA-3157 | Saqib | Removes outbound policy from sidecar --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 128a158e..9cfffffc 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 128a158e6b808d5adf225bdc72c5a99ec63448f9 +Subproject commit 9cfffffca39d37518f59eb8b6cd0738326b1d30e From 7dafdf1be2efbce6c3a779726e1c2baba0c1cfe5 Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Tue, 23 Apr 2024 19:15:22 +0530 Subject: [PATCH 070/108] INFRA-3076 | Ashvin | Migration script to add type to all manifests (#903) --- .../migration/V1.75__Add_type_field_to_manifest.sql | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/resources/db/migration/V1.75__Add_type_field_to_manifest.sql diff --git a/src/main/resources/db/migration/V1.75__Add_type_field_to_manifest.sql b/src/main/resources/db/migration/V1.75__Add_type_field_to_manifest.sql new file mode 100644 index 00000000..33dd0562 --- /dev/null +++ b/src/main/resources/db/migration/V1.75__Add_type_field_to_manifest.sql @@ -0,0 +1,12 @@ +-- Adds type field to all the manifests +-- type = flink if flink is present in the manifest +-- type = deployment if deployment is present in the manifest +-- type = deployment if type is not present in the manifest + +UPDATE manifest +SET data = jsonb_set(data, '{type}', + CASE + WHEN EXISTS (SELECT 1 FROM flink f WHERE f.manifest_id = manifest.id) THEN '"flink"'::jsonb + WHEN EXISTS (SELECT 1 FROM deployment d WHERE d.manifest_id = manifest.id) THEN '"deployment"'::jsonb + ELSE '"deployment"'::jsonb + END, TRUE); From 61e66da70298f3ddd580a4e1542a983b5a22b127 Mon Sep 17 00:00:00 2001 From: Ankit Bhardwaj Bhardwaj Date: Tue, 23 Apr 2024 19:29:37 +0530 Subject: [PATCH 071/108] INFRA-3186 | Ankit Bhardwaj | update kutegen commit hash (#902) --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 9cfffffc..f5b6cec1 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 9cfffffca39d37518f59eb8b6cd0738326b1d30e +Subproject commit f5b6cec1e512fc87fe5012cbfbd0fdbe85cf5190 From 49ffa289d383728789da6dd40086c85e54e14332 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 24 Apr 2024 15:21:52 +0530 Subject: [PATCH 072/108] INFRA-3184 | remove infraVertical key --- kutegen | 2 +- .../navi/infra/portal/controller/ManifestController.java | 2 +- .../infra/portal/service/manifest/ManifestService.java | 6 +++--- .../portal/service/ManifestServiceIntegrationTest.java | 8 ++++---- .../manifest/manifest-export-redacted-secret.json | 3 ++- .../fixtures/manifest/manifest-with-spaced-env-var.json | 3 ++- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/kutegen b/kutegen index f5b6cec1..671c84b2 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit f5b6cec1e512fc87fe5012cbfbd0fdbe85cf5190 +Subproject commit 671c84b2022cd6071a1942cdad1803135ce2b443 diff --git a/src/main/java/com/navi/infra/portal/controller/ManifestController.java b/src/main/java/com/navi/infra/portal/controller/ManifestController.java index 7b9273c4..b58dbbd2 100644 --- a/src/main/java/com/navi/infra/portal/controller/ManifestController.java +++ b/src/main/java/com/navi/infra/portal/controller/ManifestController.java @@ -81,7 +81,7 @@ public class ManifestController { } @GetMapping("/{id}/export") - public Manifest exportManifest(@PathVariable Long id) { + public Object exportManifest(@PathVariable Long id) { return manifestService.exportManifestById(id); } diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index 5aecea10..72f776cc 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -751,14 +751,14 @@ public class ManifestService { return manifestRepository.findManifestNameById(id); } - public Manifest exportManifestById(Long id) { - final Set keysToExclude = Set.of("version", "id"); + public Object exportManifestById(Long id) { + final Set keysToExclude = Set.of("version", "id", "infraVertical"); final Map keysToReplace = Map.of("isDeployed", false); var manifest = fetchById(id); var manifestAsMap = manifest.convertToMap(); ObjectTransformationUtil.removeKeys(manifestAsMap, keysToExclude); ObjectTransformationUtil.replaceKeys(manifestAsMap, keysToReplace); - return objectMapper.convertValue(manifestAsMap, Manifest.class); + return manifestAsMap; } } diff --git a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java index 14a8aed4..c3365d16 100644 --- a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java +++ b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java @@ -289,8 +289,8 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider manifestService.createOrUpdate(manifestRequest); Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("test-export", "dev"); - Manifest transformedManifest = manifestService.exportManifestById(fetchManifest.getId()); - String actualManifestJson = transformedManifest.convertToString(); + Object transformedManifest = manifestService.exportManifestById(fetchManifest.getId()); + String actualManifestJson = objectMapper.writeValueAsString(transformedManifest); assertAll(() -> assertEquals(expectedManifestGetOutputJson, actualManifestJson, false)); } @@ -306,8 +306,8 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider + "manifest-export-without-secret-access.json"); testEntityManager.merge(manifestRequest); Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("test-export", "dev"); - Manifest transformedManifest = manifestService.exportManifestById(fetchManifest.getId()); - String actualManifestJson = transformedManifest.convertToString(); + Object transformedManifest = manifestService.exportManifestById(fetchManifest.getId()); + String actualManifestJson = objectMapper.writeValueAsString(transformedManifest); assertAll(() -> assertEquals(expectedManifestGetOutputJson, actualManifestJson, false)); } } diff --git a/src/test/resources/fixtures/manifest/manifest-export-redacted-secret.json b/src/test/resources/fixtures/manifest/manifest-export-redacted-secret.json index 351e1df8..fa6572b2 100644 --- a/src/test/resources/fixtures/manifest/manifest-export-redacted-secret.json +++ b/src/test/resources/fixtures/manifest/manifest-export-redacted-secret.json @@ -148,5 +148,6 @@ "environment": "dev", "name": "test-export", "cluster": "spike.np.navi-tech.in", - "isDeployed": true + "isDeployed": true, + "infraVertical": "lending" } \ No newline at end of file diff --git a/src/test/resources/fixtures/manifest/manifest-with-spaced-env-var.json b/src/test/resources/fixtures/manifest/manifest-with-spaced-env-var.json index 0810463d..3735360b 100644 --- a/src/test/resources/fixtures/manifest/manifest-with-spaced-env-var.json +++ b/src/test/resources/fixtures/manifest/manifest-with-spaced-env-var.json @@ -48,5 +48,6 @@ }, "environment": "dev", "name": "manifest", - "cluster": "spike.np.navi-tech.in" + "cluster": "spike.np.navi-tech.in", + "infraVertical": "lending" } \ No newline at end of file From c4d851516b9a47c85d4eb469724b6b6e40eb1216 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 24 Apr 2024 17:00:08 +0530 Subject: [PATCH 073/108] INFRA-3184 | remove cluster key --- .../navi/infra/portal/controller/ManifestController.java | 2 +- .../infra/portal/service/manifest/ManifestService.java | 4 ++-- .../portal/service/ManifestServiceIntegrationTest.java | 7 +++++-- .../manifest-export-with-no-super-secret-access.json | 1 - .../manifest-export-without-secret-access.json | 1 - 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/controller/ManifestController.java b/src/main/java/com/navi/infra/portal/controller/ManifestController.java index b58dbbd2..68a6cebb 100644 --- a/src/main/java/com/navi/infra/portal/controller/ManifestController.java +++ b/src/main/java/com/navi/infra/portal/controller/ManifestController.java @@ -81,7 +81,7 @@ public class ManifestController { } @GetMapping("/{id}/export") - public Object exportManifest(@PathVariable Long id) { + public Map exportManifest(@PathVariable Long id) { return manifestService.exportManifestById(id); } diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index 72f776cc..80764314 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -751,8 +751,8 @@ public class ManifestService { return manifestRepository.findManifestNameById(id); } - public Object exportManifestById(Long id) { - final Set keysToExclude = Set.of("version", "id", "infraVertical"); + public Map exportManifestById(Long id) { + final Set keysToExclude = Set.of("version", "id", "infraVertical", "cluster"); final Map keysToReplace = Map.of("isDeployed", false); var manifest = fetchById(id); var manifestAsMap = manifest.convertToMap(); diff --git a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java index c3365d16..9370f624 100644 --- a/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java +++ b/src/test/java/com/navi/infra/portal/service/ManifestServiceIntegrationTest.java @@ -14,6 +14,7 @@ import com.navi.infra.portal.service.manifest.ManifestService; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Map; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -289,7 +290,8 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider manifestService.createOrUpdate(manifestRequest); Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("test-export", "dev"); - Object transformedManifest = manifestService.exportManifestById(fetchManifest.getId()); + Map transformedManifest = manifestService.exportManifestById( + fetchManifest.getId()); String actualManifestJson = objectMapper.writeValueAsString(transformedManifest); assertAll(() -> assertEquals(expectedManifestGetOutputJson, actualManifestJson, false)); } @@ -306,7 +308,8 @@ public class ManifestServiceIntegrationTest extends ExternalIntegrationProvider + "manifest-export-without-secret-access.json"); testEntityManager.merge(manifestRequest); Manifest fetchManifest = manifestService.fetchByNameAndEnvironment("test-export", "dev"); - Object transformedManifest = manifestService.exportManifestById(fetchManifest.getId()); + Map transformedManifest = manifestService.exportManifestById( + fetchManifest.getId()); String actualManifestJson = objectMapper.writeValueAsString(transformedManifest); assertAll(() -> assertEquals(expectedManifestGetOutputJson, actualManifestJson, false)); } diff --git a/src/test/resources/fixtures/manifest/expected_output/manifest-export-with-no-super-secret-access.json b/src/test/resources/fixtures/manifest/expected_output/manifest-export-with-no-super-secret-access.json index 71c2e626..4046ec33 100644 --- a/src/test/resources/fixtures/manifest/expected_output/manifest-export-with-no-super-secret-access.json +++ b/src/test/resources/fixtures/manifest/expected_output/manifest-export-with-no-super-secret-access.json @@ -138,6 +138,5 @@ }, "environment": "dev", "name": "test-export", - "cluster": "spike.np.navi-tech.in", "isDeployed": false } \ No newline at end of file diff --git a/src/test/resources/fixtures/manifest/expected_output/manifest-export-without-secret-access.json b/src/test/resources/fixtures/manifest/expected_output/manifest-export-without-secret-access.json index f39718ca..bca6e430 100644 --- a/src/test/resources/fixtures/manifest/expected_output/manifest-export-without-secret-access.json +++ b/src/test/resources/fixtures/manifest/expected_output/manifest-export-without-secret-access.json @@ -138,6 +138,5 @@ }, "environment": "dev", "name": "test-export", - "cluster": "spike.np.navi-tech.in", "isDeployed": false } \ No newline at end of file From 0dadcd569e035a5589af41613a079e726bcbdd61 Mon Sep 17 00:00:00 2001 From: Ashvin S Date: Wed, 24 Apr 2024 21:05:09 +0530 Subject: [PATCH 074/108] INFRA-3134 | Ashvin | Update kutegen to latest (#906) --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 671c84b2..c6531d96 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 671c84b2022cd6071a1942cdad1803135ce2b443 +Subproject commit c6531d96bc3600e40209a40d2ace99332b02cdfb From 9781da635ed0d4a367a28bc04c1e32dec254b07a Mon Sep 17 00:00:00 2001 From: Ankit Bhardwaj Bhardwaj Date: Thu, 25 Apr 2024 17:28:52 +0530 Subject: [PATCH 075/108] INFRA-3191 | Ankit Bhardwaj | fix amc prod cluster subnets (#907) * INFRA-3191 | Ankit Bhardwaj | fix amc prod cluster subnets * INFRA-3191 | Ankit Bhardwaj | update kutegen to main --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index c6531d96..2054ce08 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit c6531d96bc3600e40209a40d2ace99332b02cdfb +Subproject commit 2054ce084d5c53b3a50cc3c1e3d856f6af177e89 From 9d54910f1001a45ab0aced0c928d73b1732ee092 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Fri, 26 Apr 2024 12:46:37 +0530 Subject: [PATCH 076/108] INFRA-3188 | Dhruv | initial commit with repo setup and additional approver map --- .../service/manifest/ManifestService.java | 2 +- .../infra/portal/util/ResourceReaderUtil.java | 46 ++++++ .../service/ManifestLimitServiceImpl.java | 53 ++----- .../v2/jit/controller/JitController.java | 3 + .../portal/v2/jit/dto/JitRequestDto.java | 1 - .../portal/v2/jit/entity/JitApproval.java | 8 +- .../repository/JitApprovalsRepository.java | 16 ++ .../portal/v2/jit/service/JitServiceImpl.java | 148 ++++++++++++++++-- .../infra/portal/v2/jit/utils/AuthUtil.java | 48 ++++-- .../portal/v2/jit/utils/SlackBotUtil.java | 3 +- src/main/resources/application-dev.properties | 5 +- src/main/resources/application.properties | 1 + .../V1.76__Add_team_in_jit_approval_table.sql | 1 + src/main/resources/jit/default.yaml | 53 +++++++ src/main/resources/jit/dev.yaml | 53 +++++++ src/main/resources/jit/pref.yaml | 53 +++++++ src/main/resources/jit/prod.yaml | 53 +++++++ src/main/resources/jit/qa.yaml | 53 +++++++ .../service/ManifestLimitServiceImplTest.java | 11 +- .../v2/jit/service/JitServiceImplTest.java | 20 ++- .../portal/v2/jit/utils/AuthUtilTest.java | 60 ++++--- .../portal/v2/jit/utils/SlackBotUtilTest.java | 3 +- src/test/resources/application.properties | 3 +- 23 files changed, 567 insertions(+), 130 deletions(-) create mode 100644 src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java create mode 100644 src/main/resources/db/migration/V1.76__Add_team_in_jit_approval_table.sql create mode 100644 src/main/resources/jit/default.yaml create mode 100644 src/main/resources/jit/dev.yaml create mode 100644 src/main/resources/jit/pref.yaml create mode 100644 src/main/resources/jit/prod.yaml create mode 100644 src/main/resources/jit/qa.yaml diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index 5aecea10..45c8e891 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -752,7 +752,7 @@ public class ManifestService { } public Manifest exportManifestById(Long id) { - final Set keysToExclude = Set.of("version", "id"); + final Set keysToExclude = Set.of("version", "id", "infraVertical"); final Map keysToReplace = Map.of("isDeployed", false); var manifest = fetchById(id); var manifestAsMap = manifest.convertToMap(); diff --git a/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java b/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java new file mode 100644 index 00000000..30a1956f --- /dev/null +++ b/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java @@ -0,0 +1,46 @@ +package com.navi.infra.portal.util; + +import static java.util.Collections.emptyMap; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.ResourceLoader; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class ResourceReaderUtil { + + private static final ResourceLoader resourceLoader = new DefaultResourceLoader(); + private final ObjectMapper objectMapper; + + public ResourceReaderUtil(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @SuppressWarnings("unchecked") + public Map getResourceFromPath(List path) + throws RuntimeException { + Map map; + String pathString = String.join("/", path); + try { + final var fileInputStream = resourceLoader + .getResource(pathString) + .getInputStream(); + map = objectMapper.readValue(fileInputStream, Map.class); + } catch (FileNotFoundException e) { + log.info("File is not found in path: {}", pathString); + map = emptyMap(); + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + return map; + + } +} diff --git a/src/main/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImpl.java index 4a78115b..bba0db34 100644 --- a/src/main/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImpl.java @@ -1,75 +1,46 @@ package com.navi.infra.portal.v2.changerequest.service; -import static java.lang.String.format; -import static java.util.Collections.emptyMap; import static java.util.Collections.unmodifiableMap; -import static org.slf4j.LoggerFactory.getLogger; import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.util.MapUtil; -import java.io.FileNotFoundException; -import java.io.IOException; +import com.navi.infra.portal.util.ResourceReaderUtil; +import java.util.List; import java.util.Map; -import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Service; @Service public class ManifestLimitServiceImpl implements ManifestLimitService { - private static final Logger log = getLogger(ManifestLimitServiceImpl.class); - private final ObjectMapper yamlMapper; private final String vertical; private final String changeRequestFilepath; private final MapUtil mapUtil; - private final ResourceLoader resourceLoader; + private final ResourceReaderUtil resourceReaderUtil; public ManifestLimitServiceImpl( @Qualifier("yamlMapper") ObjectMapper yamlMapper, @Value("${portal.vertical}") String vertical, @Value("${manifest.limit.config.path}") String changeRequestFilepath, - MapUtil mapUtil, - ResourceLoader resourceLoader) { - this.yamlMapper = yamlMapper; + MapUtil mapUtil + ) { this.vertical = vertical; this.changeRequestFilepath = changeRequestFilepath; this.mapUtil = mapUtil; - this.resourceLoader = resourceLoader; + this.resourceReaderUtil = new ResourceReaderUtil(yamlMapper); } @Override - @SuppressWarnings("unchecked") public Map getLimit(String env) { + var defaultLimitMap = resourceReaderUtil.getResourceFromPath( + List.of(changeRequestFilepath, "default.yaml")); try { - final var defaultFileInputStream = resourceLoader - .getResource(format("%s/default.yaml", changeRequestFilepath)) - .getInputStream(); - final var defaultLimitMap = ((Map) yamlMapper.readValue( - defaultFileInputStream, Map.class)); - final var envLimitMap = getEnvironmentLimitMap(env); + var envLimitMap = resourceReaderUtil.getResourceFromPath( + List.of(changeRequestFilepath, vertical, env + ".yaml")); return unmodifiableMap(mapUtil.override(defaultLimitMap, envLimitMap)); - } catch (IOException e) { - throw new RuntimeException(e); + } catch (RuntimeException e) { + return unmodifiableMap(defaultLimitMap); } } - - @SuppressWarnings("unchecked") - private Map getEnvironmentLimitMap(String env) { - Map map; - try { - final var envFileInputStream = resourceLoader - .getResource(format("%s/%s/%s.yaml", changeRequestFilepath, vertical, env)) - .getInputStream(); - map = ((Map) yamlMapper.readValue(envFileInputStream, Map.class)); - } catch (FileNotFoundException e) { - log.info("Manifest limit file is not found for environment: {}", env); - map = emptyMap(); - } catch (IOException e) { - throw new RuntimeException(e); - } - return unmodifiableMap(map); - } - } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java index b240441b..1d2b077f 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/controller/JitController.java @@ -38,14 +38,17 @@ public class JitController { jitService.createJitRequest(jitRequestDto); return ResponseEntity.status(HttpStatus.CREATED).build(); } catch (IllegalArgumentException | IllegalStateException ex) { + log.error("Error creating JIT request", ex); return ResponseEntity.status(HttpStatus.BAD_REQUEST).build(); } catch (DuplicateKeyException ex) { + log.error("Error creating JIT request", ex); return ResponseEntity.status(HttpStatus.CONFLICT).build(); } catch (IOException ex) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } + @PostMapping("/approve/{reviewId}") public ResponseEntity approveJitRequest( @Valid @RequestBody JitUserDto approver, diff --git a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java index 35bdb6c9..4e4a1523 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/dto/JitRequestDto.java @@ -2,7 +2,6 @@ package com.navi.infra.portal.v2.jit.dto; import com.navi.infra.portal.v2.jit.entity.Environment; import com.navi.infra.portal.v2.jit.entity.Vertical; -import java.time.LocalDateTime; import javax.validation.constraints.Email; import javax.validation.constraints.Positive; import lombok.AllArgsConstructor; diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java index cdec3b33..1b4ed8a8 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java @@ -3,6 +3,7 @@ package com.navi.infra.portal.v2.jit.entity; import static lombok.AccessLevel.PACKAGE; import com.navi.infra.portal.domain.BaseEntity; +import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import java.time.LocalDateTime; import javax.persistence.Column; @@ -42,6 +43,10 @@ public class JitApproval extends BaseEntity { @JoinColumn(name = "reviewer_id", nullable = false) private User reviewer; + @ManyToOne + @JoinColumn(name = "team_id", nullable = false) + private Team team; + @Column(nullable = false) private LocalDateTime reviewedAt; @@ -51,9 +56,10 @@ public class JitApproval extends BaseEntity { private String reviewerSlackMessageTimestamp; - public JitApproval(JitRequest jitRequest, User reviewer, JitRequestStatus action) { + public JitApproval(JitRequest jitRequest, User reviewer, Team team, JitRequestStatus action) { this.jitRequest = jitRequest; this.reviewer = reviewer; + this.team = team; this.action = action; } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java index 0a1bbbc3..7edca74a 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java @@ -22,6 +22,22 @@ public interface JitApprovalsRepository extends JpaRepository nativeQuery = true) Long findApprovedRequestsCount(Long jitId); + @Query(value = "SELECT COUNT(CASE WHEN ja.action = 'APPROVED' THEN 1 END) " + + "FROM jit_approvals ja WHERE ja.jit_id = :jitId " + + "GROUP BY ja.team_id", + nativeQuery = true) + List countApprovedInEachTeam(Long jitId); + + default Long findTotalApprovalsIfAllTeamsApproved(Long jitId) { + List approvalList = countApprovedInEachTeam(jitId); + long totalApproved = approvalList.stream() + .mapToLong(Long::longValue) + .sum(); + boolean allTeamApproval = approvalList.stream() + .allMatch(approval -> approval >= 1); + return allTeamApproval ? totalApproved : 0; + } + @Query(value = "SELECT ja.reviewer_id FROM jit_approvals ja " + "WHERE ja.jit_id = :jitId and ja.action = :action", nativeQuery = true) List findReviewersByAction(Long jitId, String action); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index e6c6dc1a..206e97d8 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -1,9 +1,14 @@ package com.navi.infra.portal.v2.jit.service; +import static java.util.Collections.unmodifiableMap; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; +import com.navi.infra.portal.util.MapUtil; +import com.navi.infra.portal.util.ResourceReaderUtil; import com.navi.infra.portal.v2.client.airflow.AirflowClient; import com.navi.infra.portal.v2.jit.dto.JitRequestDto; import com.navi.infra.portal.v2.jit.entity.JitApproval; @@ -14,7 +19,6 @@ import com.navi.infra.portal.v2.jit.repository.JitRequestsRepository; import com.navi.infra.portal.v2.jit.utils.AuthUtil; import com.navi.infra.portal.v2.jit.utils.SlackBotUtil; import com.navi.infra.portal.v2.jit.utils.SlackColor; -import com.navi.infra.portal.v2.privilege.ResourceType; import com.navi.infra.portal.v2.role.RoleService; import com.navi.infra.portal.v2.slackbotclient.SlackBotAttachment; import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; @@ -30,15 +34,14 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; -import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service -@RequiredArgsConstructor @Slf4j class JitServiceImpl implements JitService { @@ -47,6 +50,7 @@ class JitServiceImpl implements JitService { private final JitRequestsRepository jitRequestRepository; private final JitApprovalsRepository jitApprovalsRepository; private final SlackBotUtil slackBotUtil; + private final MapUtil mapUtil; private final AuthUtil authUtil; private final AirflowClient airflowClient; private final SlackBotClient slackBotClient; @@ -54,14 +58,49 @@ class JitServiceImpl implements JitService { private final UserService userService; private final RoleService roleService; private final TeamService teamService; - private final ResourceType resourceType = null; - private final String env = null; - - @Value("${jit.dag.id}") - private String dagId; - + private final ResourceReaderUtil resourceReaderUtil; + private final String dagId; + private final String requestConfigPath; @Value("${jit.slack.common.channel.id}") - private String commonChannelId; + private final String commonChannelId; + ObjectMapper yamlMapper; + + public JitServiceImpl( + JitRequestsRepository jitRequestRepository, + JitApprovalsRepository jitApprovalsRepository, + SlackBotUtil slackBotUtil, + MapUtil mapUtil, + AuthUtil authUtil, + AirflowClient airflowClient, + SlackBotClient slackBotClient, + ObjectMapper objectMapper, + UserService userService, + RoleService roleService, + TeamService teamService, + @Qualifier("yamlMapper") ObjectMapper yamlMapper, + @Value("${jit.dag.id}") String dagId, + @Value("${jit.request.config.path}") String requestConfigPath, + @Value("${jit.slack.common.channel.id}") String commonChannelId + + ) { + this.jitRequestRepository = jitRequestRepository; + this.jitApprovalsRepository = jitApprovalsRepository; + this.slackBotUtil = slackBotUtil; + this.mapUtil = mapUtil; + this.authUtil = authUtil; + this.airflowClient = airflowClient; + this.slackBotClient = slackBotClient; + this.objectMapper = objectMapper; + this.userService = userService; + this.roleService = roleService; + this.teamService = teamService; + this.yamlMapper = yamlMapper; + this.resourceReaderUtil = new ResourceReaderUtil(yamlMapper); + this.dagId = dagId; + this.requestConfigPath = requestConfigPath; + this.commonChannelId = commonChannelId; + } + private boolean duplicateRequest(JitRequest jitRequest) { List existingDuplicates = jitRequestRepository.findDuplicateRequestsByUser( @@ -113,7 +152,8 @@ class JitServiceImpl implements JitService { } private void updateRequestorRequestNotAllowed(JitRequest jitRequest) throws IOException { - SlackBotAttachment personalMessage = slackBotUtil.getRequestorRequestNotAllowedDm(jitRequest); + SlackBotAttachment personalMessage = slackBotUtil.getRequestorRequestNotAllowedDm( + jitRequest); slackBotClient.postMessage( userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); } @@ -191,10 +231,13 @@ class JitServiceImpl implements JitService { throw new IllegalStateException("Request already reviewed"); } jitApproval.setReviewedAt(LocalDateTime.now()); + var additionalApprovalTeams = getAdditionalApprovalTeams( + jitRequest.getEnvironment().type, + jitRequest.getResourceType(), jitRequest.getResourceAction()); if (!reviewerEmail.equals(jitApproval.getReviewer().getEmail()) - && !authUtil.isAuthorized(reviewerEmail, jitRequest) - && reviewerEmail.equals(jitRequest.getRequestedFor().getEmail())) { + || !authUtil.isAuthorized(reviewerEmail, jitRequest, additionalApprovalTeams) + || reviewerEmail.equals(jitRequest.getRequestedFor().getEmail())) { log.error("User {} not allowed to perform action", reviewerEmail); throw new IllegalAccessException("User not allowed to perform action"); } @@ -230,7 +273,7 @@ class JitServiceImpl implements JitService { try { boolean actionEnabled = true; - if (authUtil.checkRequiredApprovals(jitRequest)) { + if (authUtil.haveRequiredApprovals(jitRequest)) { // if required number of approvals are met, // 1. schedule JIT(just in time) DAGs - one for grant and another for grant, // 2. inform user on slack that request is approved, @@ -267,7 +310,6 @@ class JitServiceImpl implements JitService { } } - private void jitRejectedFlow( String reviewerEmail, JitApproval jitApproval, @@ -318,6 +360,47 @@ class JitServiceImpl implements JitService { } } + public Map getAdditionalApprovalMap(String env) { + var defaultLimitMap = resourceReaderUtil.getResourceFromPath( + List.of(requestConfigPath, "default.yaml")); + try { + var envLimitMap = resourceReaderUtil.getResourceFromPath( + List.of(requestConfigPath, env + ".yaml")); + return unmodifiableMap(mapUtil.override(defaultLimitMap, envLimitMap)); + } catch (RuntimeException e) { + return unmodifiableMap(defaultLimitMap); + } + } + + + @SuppressWarnings("unchecked") + public List getAdditionalApprovalTeams( + String env, + String resourceType, + String resourceAction + ) { + var additionalApprovalMap = getAdditionalApprovalMap(env); + String jsonPath = String.format("/resources/%s/%s/approvalFrom", resourceType, + resourceAction); + var result = mapUtil.getValueAtPath(additionalApprovalMap, jsonPath); + if (result instanceof List) { + return (List) result; + } + return new ArrayList<>(); + } + + private Map> getAdditionalTeamsAndReviewer( + List teams, + String env, + String userEmail + ) { + return teams.stream().collect(Collectors.toMap( + teamService::findByName, + team -> authUtil.getReviewers(team, env).stream().filter( + user -> !user.getEmail().equals(userEmail)).collect(Collectors.toList() + ))); + } + private JitRequest mapToJitRequest(JitRequestDto jitRequestDto) { return new JitRequest(userService.findUserByEmail(jitRequestDto.getRequestedFor()), userService.findUserByEmail(jitRequestDto.getRequestedBy()), @@ -341,11 +424,13 @@ class JitServiceImpl implements JitService { } // Determine the reviewers based on REQUEST - List reviewers = authUtil.getReviewers(jitRequestDto) + List reviewers = authUtil.getReviewers(jitRequest.getTeam().getName(), + jitRequest.getEnvironment().type) .stream() .distinct() .filter(user -> !user.getEmail().equals(jitRequest.getRequestedFor().getEmail())) .collect(Collectors.toList()); + log.info("Requesting review from {}", reviewers); if (reviewers.size() == 0) { @@ -353,11 +438,36 @@ class JitServiceImpl implements JitService { updateRequestorNoReviewersDmOnSlack(jitRequest); throw new IllegalStateException("No reviewers found"); } + + var additionalTeams = getAdditionalApprovalTeams( + jitRequestDto.getEnvironment().type, jitRequestDto.getResourceType(), + jitRequestDto.getResourceAction()); + additionalTeams.remove(jitRequestDto.getTeam()); + + Map> additionalTeamReviewers = getAdditionalTeamsAndReviewer( + additionalTeams, + jitRequest.getEnvironment().type, + jitRequest.getRequestedFor().getEmail() + ); + var teamsWithoutUsers = additionalTeamReviewers.entrySet().stream() + .filter(entry -> entry.getValue().isEmpty()) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + + if (!teamsWithoutUsers.isEmpty()) { + // no reviwers found for additional teams, inform user + updateRequestorNoReviewersDmOnSlack(jitRequest); + throw new IllegalStateException( + "No reviewers found for additional teams : " + teamsWithoutUsers.stream() + .map(Team::getName).collect(Collectors.joining(","))); + } + List jitApprovals = new ArrayList<>(); List pendingReviewers = new ArrayList<>(); for (User reviewer : reviewers) { JitApproval jitApproval = new JitApproval(jitRequest, reviewer, + jitRequest.getTeam(), JitRequestStatus.PENDING); jitApprovals.add(jitApproval); @@ -365,6 +475,12 @@ class JitServiceImpl implements JitService { String reviewersEmail = reviewer.getEmail(); pendingReviewers.add(reviewersEmail); } + additionalTeamReviewers.forEach((team, users) -> users.forEach(reviewer -> { + JitApproval jitApproval = new JitApproval(jitRequest, reviewer, team, + JitRequestStatus.PENDING); + jitApprovals.add(jitApproval); + pendingReviewers.add(reviewer.getEmail()); + })); // send personal message to user with details on pending and approved reviewers JitRequest jitRequestWithId = jitRequestRepository.save(jitRequest); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 727af739..979f2622 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -5,7 +5,6 @@ import static com.navi.infra.portal.v2.role.Actor.JITREVIEWER; import com.navi.infra.portal.domain.user.Role; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; -import com.navi.infra.portal.v2.jit.dto.JitRequestDto; import com.navi.infra.portal.v2.jit.entity.Environment; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; @@ -14,6 +13,7 @@ import com.navi.infra.portal.v2.role.RoleService; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -33,13 +33,23 @@ public class AuthUtil { @Value("${jit.number_of_nonprod_approvals}") private Long nonprodJitApprovalsCount; - public boolean isAuthorized(String userEmail, JitRequest jitRequest) { + + public boolean isAuthorized( + String userEmail, + JitRequest jitRequest, + List additionalTeams + ) { User user = userService.findUserByEmail(userEmail); List userRoles = user.getRoles().stream().map(Role::getName) .collect(Collectors.toList()); + + var allTeams = new ArrayList(); + allTeams.add(jitRequest.getTeam().getName()); + allTeams.addAll(additionalTeams); + return userRoles.stream() .filter(role -> role.contains(JITREVIEWER.toString()) - && (role.contains(jitRequest.getTeam().getName())) + && allTeams.stream().anyMatch(role::contains) || role.contains("PORTAL")) .anyMatch(role -> role.contains(jitRequest.getEnvironment().type) || role.contains("ALL") @@ -56,27 +66,31 @@ public class AuthUtil { .collect(Collectors.toList()); } - public boolean checkRequiredApprovals(JitRequest jitRequest) { + public boolean haveRequiredApprovals(JitRequest jitRequest) { Environment env = jitRequest.getEnvironment(); - Long approvedRequests = jitApprovalsRepository.findApprovedRequestsCount( + Long approvedRequests = jitApprovalsRepository.findTotalApprovalsIfAllTeamsApproved( jitRequest.getId()); + // is atleast one approval from each required team obtained based on the mapping in yaml + // and required approval type (master or something) return approvedRequests >= env.approvals; } - public List getReviewers(JitRequestDto jitRequestDto) { + public List getReviewersFromRole(String teamName, String reviewerRoleType) { + Role reviewerRole = new Role(String.join("_", teamName, + reviewerRoleType, JITREVIEWER.toString())); + return userService.getUsersWithRole(reviewerRole.getName()); + } + + // public List + public List getReviewers(String teamName, String environmentType) { // Determine the reviewers based on REQUEST - List reviewers = new ArrayList<>(); - Role reviewerRole = new Role(String.join("_", jitRequestDto.getTeam(), - jitRequestDto.getEnvironment().toString().toLowerCase(), JITREVIEWER.toString())); - List environmentSpecificReviewers = userService.getUsersWithRole( - reviewerRole.getName()); - reviewerRole = new Role( - String.join("_", jitRequestDto.getTeam(), "ALL", JITREVIEWER.toString())); - List allEnvironmentReviewers = userService.getUsersWithRole(reviewerRole.getName()); - reviewers.addAll(environmentSpecificReviewers); - reviewers.addAll(allEnvironmentReviewers); + List environmentSpecificReviewers = getReviewersFromRole(teamName, environmentType); + List allEnvironmentReviewers = getReviewersFromRole(teamName, "ALL"); + + return Stream.concat(environmentSpecificReviewers.stream(), + allEnvironmentReviewers.stream()) + .collect(Collectors.toList()); // TODO Add exception in case no reviewers found // TODO reduce number of userService calls thereby reducing DB calls - return reviewers; } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index f2b4f294..ff58026d 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -136,7 +136,7 @@ public class SlackBotUtil { ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format( - "No Reviewers present for team: %s. Kindly get notify team to have reviewers. " + "No Reviewers present for team(s): %s. Kindly get notify team to have reviewers. " + "Contact Cloud Platform oncall if issue persists", jitRequest.getTeam().getName())); @@ -152,6 +152,7 @@ public class SlackBotUtil { public SlackBotAttachment getRequestorRequestNotAllowedDm( JitRequest jitRequest ) { + // TODO: No placeholder for team names :| SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format( "Request for same resource in the specified window already exists. " diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 750e5b75..bef8b5d9 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -19,13 +19,10 @@ management.metrics.export.prometheus.enabled=true management.server.port=4001 config.manifestAudit.maxAuditCount=${MANIFEST_AUDIT_COUNT:10} spring.main.allow-bean-definition-overriding=true - #JWT token generation jwt.secret.key=${JWT_SECRET_KEY} - #Teams List from Vault - Single source of truth for teams in vault teams.list.vault=${TEAMS_LIST_VAULT} - #AWS Profile aws.region=ap-south-1 aws.profile=${AWS_PROFILE:default} @@ -33,8 +30,8 @@ airflow.url=${AIRFLOW_URL} airflow.token=${AIRFLOW_AUTH_TOKEN} service-dump.dag.id=${SERVICE_DUMP_DAG_ID:kubectl_get_pod} service-dump.image.name=${SERVICE_DUMP_IMAGE_NAME:193044292705.dkr.ecr.ap-south-1.amazonaws.com/common/openjdk:11.0.16-user4k} - #Just In Time Access slackbot.token=${SLACK_BOT_TOKEN:xoxb-format-12345} jit.dag.id=${JIT_DAG_ID:jit_dag} jit.slack.common.channel.id=${JIT_COMMON_CHANNEL:C06NDTBFA1G} +jit.request.config.path=classpath:jit diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3bf27ca5..8452da9d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -53,6 +53,7 @@ ecr.dockerRegistryNamespace=${DOCKER_REGISTRY_NAMESPACE:medici} config.deployment.strategyNameMapping={'rollingUpdateWithCanary': 'rollingUpdateWithCanaryMixIn', 'canary': 'canary', 'rollingUpdate': 'rollingUpdate'} config.manifestAudit.maxAuditCount=${MANIFEST_AUDIT_COUNT:10} spring.main.allow-bean-definition-overriding=true +jit.request.config.path=classpath:jit manifest.limit.config.path=classpath:changerequest environment.list=cmd,prod,dev,qa,perf,uat,data-platform-prod,data-platform-nonprod,local environment.role.privileges.map={'cmd': 'cmd', 'prod': 'prod', 'dev': 'dev', 'qa': 'qa', 'perf': 'perf', 'uat': 'uat', 'data-platform-prod': 'data-platform-prod', 'data-platform-nonprod': 'data-platform-nonprod', 'local': 'local', 'ALL': '.*'} diff --git a/src/main/resources/db/migration/V1.76__Add_team_in_jit_approval_table.sql b/src/main/resources/db/migration/V1.76__Add_team_in_jit_approval_table.sql new file mode 100644 index 00000000..d981631a --- /dev/null +++ b/src/main/resources/db/migration/V1.76__Add_team_in_jit_approval_table.sql @@ -0,0 +1 @@ +ALTER TABLE jit_approvals ADD COLUMN team_id BIGINT NOT NULL REFERENCES team(id); \ No newline at end of file diff --git a/src/main/resources/jit/default.yaml b/src/main/resources/jit/default.yaml new file mode 100644 index 00000000..0fff4ab7 --- /dev/null +++ b/src/main/resources/jit/default.yaml @@ -0,0 +1,53 @@ +resources: + AWS: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + RDS: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + K8S: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + DB: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra \ No newline at end of file diff --git a/src/main/resources/jit/dev.yaml b/src/main/resources/jit/dev.yaml new file mode 100644 index 00000000..0fff4ab7 --- /dev/null +++ b/src/main/resources/jit/dev.yaml @@ -0,0 +1,53 @@ +resources: + AWS: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + RDS: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + K8S: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + DB: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra \ No newline at end of file diff --git a/src/main/resources/jit/pref.yaml b/src/main/resources/jit/pref.yaml new file mode 100644 index 00000000..0fff4ab7 --- /dev/null +++ b/src/main/resources/jit/pref.yaml @@ -0,0 +1,53 @@ +resources: + AWS: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + RDS: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + K8S: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + DB: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra \ No newline at end of file diff --git a/src/main/resources/jit/prod.yaml b/src/main/resources/jit/prod.yaml new file mode 100644 index 00000000..0fff4ab7 --- /dev/null +++ b/src/main/resources/jit/prod.yaml @@ -0,0 +1,53 @@ +resources: + AWS: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + RDS: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + K8S: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + DB: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra \ No newline at end of file diff --git a/src/main/resources/jit/qa.yaml b/src/main/resources/jit/qa.yaml new file mode 100644 index 00000000..0fff4ab7 --- /dev/null +++ b/src/main/resources/jit/qa.yaml @@ -0,0 +1,53 @@ +resources: + AWS: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + RDS: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + K8S: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra + DB: + master: + approvalFrom: + - Security + - Infra + read: + approvalFrom: + - Security + - Infra + admin: + approvalFrom: + - Security + - Infra \ No newline at end of file diff --git a/src/test/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImplTest.java index f6a11d27..fe2c6cbc 100644 --- a/src/test/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImplTest.java @@ -15,8 +15,6 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.ResourceLoader; import org.springframework.util.ResourceUtils; @ExtendWith(MockitoExtension.class) @@ -26,15 +24,15 @@ public class ManifestLimitServiceImplTest { private final MapUtil mapUtil = new MapUtil(); private final String VERTICAL_LENDING = "lending"; private final String PATH_TO_LIMIT_FILES = "classpath:changerequest"; - private final ResourceLoader resourceLoader = new DefaultResourceLoader(); private ManifestLimitServiceImpl service; @Test @DisplayName("should raise exception if default file is not found") void shouldRaiseExceptionIfDefaultFileIsNotFound() { service = new ManifestLimitServiceImpl(yamlMapper, "non-existent-vertical", - "non-existent-path", null, - resourceLoader); + "non-existent-path", mapUtil + ); + final var exception = assertThrows(RuntimeException.class, () -> service.getLimit("")); assertEquals( "java.io.FileNotFoundException: class path resource [non-existent-path/default.yaml] cannot be " @@ -51,8 +49,7 @@ public class ManifestLimitServiceImplTest { }) void shouldReturnOverriddenMap(String env, String expectedFilepath) throws IOException { service = new ManifestLimitServiceImpl(yamlMapper, VERTICAL_LENDING, PATH_TO_LIMIT_FILES, - mapUtil, - resourceLoader); + mapUtil); final var actual = service.getLimit(env); final var expected = readYaml(format("%s/%s", PATH_TO_LIMIT_FILES, expectedFilepath)); assertEquals(expected, actual); diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java index 18b481f6..f54ead5a 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -5,9 +5,12 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; +import com.navi.infra.portal.util.MapUtil; +import com.navi.infra.portal.util.ResourceReaderUtil; import com.navi.infra.portal.v2.client.airflow.AirflowClient; import com.navi.infra.portal.v2.jit.dto.JitRequestDto; import com.navi.infra.portal.v2.jit.entity.Environment; @@ -34,6 +37,7 @@ public class JitServiceImplTest { JitApprovalsRepository.class); private final SlackBotUtil slackBotUtil = mock(SlackBotUtil.class); private final AuthUtil authUtil = mock(AuthUtil.class); + private final MapUtil mapUtil = new MapUtil(); private final AirflowClient airflowClient = mock(AirflowClient.class); private final SlackBotClient slackBotClient = mock(SlackBotClient.class); @@ -42,10 +46,12 @@ public class JitServiceImplTest { private final RoleService roleService = mock(RoleService.class); private final TeamService teamService = mock(TeamService.class); private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory()); + private final ResourceReaderUtil resourceReaderUtil = new ResourceReaderUtil(yamlMapper); JitServiceImpl jitServiceImpl = new JitServiceImpl(jitRequestRepository, jitApprovalsRepository, - slackBotUtil, authUtil, airflowClient, slackBotClient, objectMapper, userService, - roleService, teamService); + slackBotUtil, mapUtil, authUtil, airflowClient, slackBotClient, objectMapper, userService, + roleService, teamService, yamlMapper, null, "classpath:jit", "null"); User requestedFor = new User(); User requestedBy = new User(); JitRequestDto jitRequestDto = new JitRequestDto("alpha@one.com", "beta@two.com", @@ -61,7 +67,8 @@ public class JitServiceImplTest { when(userService.findUserByEmail("beta@two.com")).thenReturn(requestedBy); JitRequest jitRequestWithId = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, - new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, + List.of(new Team("Infra")), Environment.PROD, "RDS", "dev-db", "read", + JitRequestStatus.PENDING, 1L, LocalDateTime.now()); jitRequestWithId.setId(1L); when(jitRequestRepository.save(any())).thenReturn(jitRequestWithId); @@ -71,10 +78,11 @@ public class JitServiceImplTest { User reviewerTwo = new User(); reviewerTwo.setEmail("delte@four.com"); List reviewers = List.of(reviewerOne, reviewerTwo); - when(authUtil.getReviewers(jitRequestDto)).thenReturn(reviewers); + when(authUtil.getReviewers(jitRequestWithId)).thenReturn(reviewers); JitRequest jitRequest = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, - new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, + List.of(new Team("Infra")), Environment.PROD, "RDS", "dev-db", "read", + JitRequestStatus.PENDING, 1L, LocalDateTime.now()); JitApproval jitApprovalOne = new JitApproval(jitRequest, reviewerOne, JitRequestStatus.PENDING); @@ -89,7 +97,7 @@ public class JitServiceImplTest { List jitApprovals = List.of(jitApprovalOne, jitApprovalTwo); List jitApprovalsWithId = List.of(jitApprovalOneWithId, jitApprovalTwoWithId); - when(teamService.findByName("Infra")).thenReturn(new Team("Infra")); + when(teamService.findByNames(List.of("Infra"))).thenReturn(List.of(new Team("Infra"))); when(userService.getUsersSlackId(jitRequest.getRequestedFor())).thenReturn("U12314"); when(slackBotClient.postMessage(any(), any())).thenReturn("2341419824719"); when(jitApprovalsRepository.saveAll(jitApprovals)).thenReturn(jitApprovalsWithId); diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java index b6281c46..aedc7b2c 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -8,18 +8,14 @@ import com.navi.infra.portal.domain.user.Role; import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; -import com.navi.infra.portal.v2.jit.dto.JitRequestDto; import com.navi.infra.portal.v2.jit.entity.Environment; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; import com.navi.infra.portal.v2.role.RoleService; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.Assert; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.test.util.ReflectionTestUtils; @@ -45,7 +41,7 @@ public class AuthUtilTest { @DisplayName("Check if the user authorized and has specific role") public void testIsAuthorized() { JitRequest jitRequest = new JitRequest(); - jitRequest.setTeam(new Team("Infra")); + jitRequest.setTeams(List.of(new Team("Infra"))); jitRequest.setEnvironment(Environment.PROD); String testEmail = "alpha@one.com"; User testUser = new User(); @@ -84,7 +80,7 @@ public class AuthUtilTest { when(jitApprovalsRepository.findApprovedRequestsCount(jitRequest.getId())) .thenReturn(2L); - boolean result = authUtil.checkRequiredApprovals(jitRequest); + boolean result = authUtil.haveRequiredApprovals(jitRequest); Assert.assertTrue(result); } @@ -100,34 +96,34 @@ public class AuthUtilTest { when(jitApprovalsRepository.findApprovedRequestsCount(jitRequest.getId())) .thenReturn(1L); - boolean result = authUtil.checkRequiredApprovals(jitRequest); + boolean result = authUtil.haveRequiredApprovals(jitRequest); Assert.assertTrue(result); } - @Test - @DisplayName("Should be able to get reviewers for certain combination of team and environment") - public void testGetReviewers() { - JitRequestDto mockRequestDto = new JitRequestDto(); - mockRequestDto.setTeam("Infra"); - mockRequestDto.setEnvironment(Environment.DEV); - - User reviewer1 = new User(); - reviewer1.setEmail("reviewer1@domain.com"); - User reviewer2 = new User(); - reviewer2.setEmail("reviewer2@domain.com"); - List specificRoleReviewers = new ArrayList<>(Arrays.asList(reviewer1)); - List allReviewers = Arrays.asList(reviewer2); - - when(userService.getUsersWithRole("Infra_dev_JITREVIEWER")) - .thenReturn(specificRoleReviewers); - when(userService.getUsersWithRole("Infra_ALL_JITREVIEWER")) - .thenReturn(allReviewers); - - List result = authUtil.getReviewers(mockRequestDto); - - Assertions.assertEquals(2, result.size()); - Assertions.assertTrue(result.contains(reviewer1)); - Assertions.assertTrue(result.contains(reviewer2)); - } +// @Test +// @DisplayName("Should be able to get reviewers for certain combination of team and environment") +// public void testGetReviewers() { +// JitRequestDto mockRequestDto = new JitRequestDto(); +// mockRequestDto.setTeam("Infra"); +// mockRequestDto.setEnvironment(Environment.DEV); +// +// User reviewer1 = new User(); +// reviewer1.setEmail("reviewer1@domain.com"); +// User reviewer2 = new User(); +// reviewer2.setEmail("reviewer2@domain.com"); +// List specificRoleReviewers = new ArrayList<>(List.of(reviewer1)); +// List allReviewers = List.of(reviewer2); +// +// when(userService.getUsersWithRole("Infra_dev_JITREVIEWER")) +// .thenReturn(specificRoleReviewers); +// when(userService.getUsersWithRole("Infra_ALL_JITREVIEWER")) +// .thenReturn(allReviewers); +// +// List result = authUtil.getReviewers(mockRequestDto); +// +// Assertions.assertEquals(2, result.size()); +// Assertions.assertTrue(result.contains(reviewer1)); +// Assertions.assertTrue(result.contains(reviewer2)); +// } } diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java index a8c1e279..111c63ed 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java @@ -10,6 +10,7 @@ import com.navi.infra.portal.v2.jit.entity.Vertical; import com.navi.infra.portal.v2.slackbotclient.SlackBotAttachment; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -19,7 +20,7 @@ public class SlackBotUtilTest { String userEmail = "test@domain.com"; JitRequest jitRequest = new JitRequest(new User(), new User(), Vertical.SA, - new Team("Infra"), Environment.DEV, "RDS", "dev-db", + List.of(new Team("Infra")), Environment.DEV, "RDS", "dev-db", "read", JitRequestStatus.PENDING, 5L, LocalDateTime.now()); JitApproval jitApproval = new JitApproval(); diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 8e2deed1..a965611a 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -43,15 +43,14 @@ ecr.dockerRegistryNamespace=lending config.deployment.strategyNameMapping={'rollingUpdateWithCanary': 'rollingUpdateWithCanaryMixIn', 'canary': 'canary', 'rollingUpdate': 'rollingUpdate'} config.manifestAudit.maxAuditCount=${MANIFEST_AUDIT_COUNT:10} spring.main.allow-bean-definition-overriding=true +jit.request.config.path=classpath:jit manifest.limit.config.path=classpath:changerequest environment.list=cmd,prod,dev,qa,perf,uat,data-platform-prod,data-platform-nonprod environment.role.privileges.map={'cmd': 'cmd', 'prod': 'prod', 'dev': 'dev', 'qa': 'qa', 'perf': 'perf', 'uat': 'uat', 'data-platform-prod': 'data-platform-prod', 'data-platform-nonprod': 'data-platform-nonprod', 'local': 'local', 'ALL': '.*'} manifest.deployment.loadbalancer.groupname.threshold=60 jwt.secret.key=${JWT_SECRET_KEY:test-secret-key} - #Teams List from Vault - Single source of truth for teams in vault teams.list.vault=${TEAMS_LIST_VAULT:InsurancePlatform,Co-Lending,IT,Infra} - #AWS Profile aws.region=ap-south-1 aws.profile=${AWS_PROFILE:default} From 545ffe7f8d216b1b6a7955f97039ac27a919fca3 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Fri, 26 Apr 2024 14:20:33 +0530 Subject: [PATCH 077/108] INFRA-3188 | Dhruv | fix existing tests --- .../portal/v2/jit/service/JitServiceImpl.java | 32 ++-------- .../v2/jit/utils/ApprovalMapProvider.java | 55 ++++++++++++++++ .../v2/jit/service/JitServiceImplTest.java | 42 +++++++++---- .../portal/v2/jit/utils/AuthUtilTest.java | 62 ++++++++++--------- .../portal/v2/jit/utils/SlackBotUtilTest.java | 3 +- 5 files changed, 124 insertions(+), 70 deletions(-) create mode 100644 src/main/java/com/navi/infra/portal/v2/jit/utils/ApprovalMapProvider.java diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 206e97d8..cdb4258b 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -1,14 +1,11 @@ package com.navi.infra.portal.v2.jit.service; -import static java.util.Collections.unmodifiableMap; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; import com.navi.infra.portal.util.MapUtil; -import com.navi.infra.portal.util.ResourceReaderUtil; import com.navi.infra.portal.v2.client.airflow.AirflowClient; import com.navi.infra.portal.v2.jit.dto.JitRequestDto; import com.navi.infra.portal.v2.jit.entity.JitApproval; @@ -52,18 +49,17 @@ class JitServiceImpl implements JitService { private final SlackBotUtil slackBotUtil; private final MapUtil mapUtil; private final AuthUtil authUtil; + + private final Map> additionalApprovalMap; private final AirflowClient airflowClient; private final SlackBotClient slackBotClient; private final ObjectMapper objectMapper; private final UserService userService; private final RoleService roleService; private final TeamService teamService; - private final ResourceReaderUtil resourceReaderUtil; private final String dagId; - private final String requestConfigPath; @Value("${jit.slack.common.channel.id}") private final String commonChannelId; - ObjectMapper yamlMapper; public JitServiceImpl( JitRequestsRepository jitRequestRepository, @@ -77,9 +73,9 @@ class JitServiceImpl implements JitService { UserService userService, RoleService roleService, TeamService teamService, - @Qualifier("yamlMapper") ObjectMapper yamlMapper, + @Qualifier("additionalApprovalMap") + Map> additionalApprovalMap, @Value("${jit.dag.id}") String dagId, - @Value("${jit.request.config.path}") String requestConfigPath, @Value("${jit.slack.common.channel.id}") String commonChannelId ) { @@ -94,10 +90,8 @@ class JitServiceImpl implements JitService { this.userService = userService; this.roleService = roleService; this.teamService = teamService; - this.yamlMapper = yamlMapper; - this.resourceReaderUtil = new ResourceReaderUtil(yamlMapper); + this.additionalApprovalMap = additionalApprovalMap; this.dagId = dagId; - this.requestConfigPath = requestConfigPath; this.commonChannelId = commonChannelId; } @@ -360,29 +354,15 @@ class JitServiceImpl implements JitService { } } - public Map getAdditionalApprovalMap(String env) { - var defaultLimitMap = resourceReaderUtil.getResourceFromPath( - List.of(requestConfigPath, "default.yaml")); - try { - var envLimitMap = resourceReaderUtil.getResourceFromPath( - List.of(requestConfigPath, env + ".yaml")); - return unmodifiableMap(mapUtil.override(defaultLimitMap, envLimitMap)); - } catch (RuntimeException e) { - return unmodifiableMap(defaultLimitMap); - } - } - - @SuppressWarnings("unchecked") public List getAdditionalApprovalTeams( String env, String resourceType, String resourceAction ) { - var additionalApprovalMap = getAdditionalApprovalMap(env); String jsonPath = String.format("/resources/%s/%s/approvalFrom", resourceType, resourceAction); - var result = mapUtil.getValueAtPath(additionalApprovalMap, jsonPath); + var result = mapUtil.getValueAtPath(additionalApprovalMap.get(env), jsonPath); if (result instanceof List) { return (List) result; } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/ApprovalMapProvider.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/ApprovalMapProvider.java new file mode 100644 index 00000000..b4376ad2 --- /dev/null +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/ApprovalMapProvider.java @@ -0,0 +1,55 @@ +package com.navi.infra.portal.v2.jit.utils; + +import static java.util.Collections.unmodifiableMap; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.navi.infra.portal.util.MapUtil; +import com.navi.infra.portal.util.ResourceReaderUtil; +import com.navi.infra.portal.v2.jit.entity.Environment; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +@Component +public class ApprovalMapProvider { + + private final ResourceReaderUtil resourceReaderUtil; + private final MapUtil mapUtil; + private final String requestConfigPath; + + public ApprovalMapProvider( + MapUtil mapUtil, + @Qualifier("yamlMapper") ObjectMapper yamlMapper, + @Value("${jit.request.config.path}") String requestConfigPath + ) { + this.resourceReaderUtil = new ResourceReaderUtil(yamlMapper); + this.mapUtil = mapUtil; + this.requestConfigPath = requestConfigPath; + } + + public Map getAdditionalApprovalMap(String env) { + var defaultLimitMap = resourceReaderUtil.getResourceFromPath( + List.of(requestConfigPath, "default.yaml")); + try { + var envLimitMap = resourceReaderUtil.getResourceFromPath( + List.of(requestConfigPath, env + ".yaml")); + return unmodifiableMap(mapUtil.override(defaultLimitMap, envLimitMap)); + } catch (RuntimeException e) { + return unmodifiableMap(defaultLimitMap); + } + } + + @Bean("additionalApprovalMap") + public Map> additionalApprovalMap() { + Environment[] environments = Environment.values(); + Map> approvalMap = new HashMap<>(); + for (Environment env : environments) { + approvalMap.put(env.type, getAdditionalApprovalMap(env.type)); + } + return unmodifiableMap(approvalMap); + } +} \ No newline at end of file diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java index f54ead5a..d38d31f7 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -10,7 +10,6 @@ import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; import com.navi.infra.portal.util.MapUtil; -import com.navi.infra.portal.util.ResourceReaderUtil; import com.navi.infra.portal.v2.client.airflow.AirflowClient; import com.navi.infra.portal.v2.jit.dto.JitRequestDto; import com.navi.infra.portal.v2.jit.entity.Environment; @@ -20,6 +19,7 @@ import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.entity.Vertical; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; import com.navi.infra.portal.v2.jit.repository.JitRequestsRepository; +import com.navi.infra.portal.v2.jit.utils.ApprovalMapProvider; import com.navi.infra.portal.v2.jit.utils.AuthUtil; import com.navi.infra.portal.v2.jit.utils.SlackBotUtil; import com.navi.infra.portal.v2.role.RoleService; @@ -28,9 +28,10 @@ import com.navi.infra.portal.v2.team.TeamService; import java.io.IOException; import java.time.LocalDateTime; import java.util.List; +import java.util.Map; import org.junit.jupiter.api.Test; -public class JitServiceImplTest { +class JitServiceImplTest { private final JitRequestsRepository jitRequestRepository = mock(JitRequestsRepository.class); private final JitApprovalsRepository jitApprovalsRepository = mock( @@ -38,7 +39,6 @@ public class JitServiceImplTest { private final SlackBotUtil slackBotUtil = mock(SlackBotUtil.class); private final AuthUtil authUtil = mock(AuthUtil.class); private final MapUtil mapUtil = new MapUtil(); - private final AirflowClient airflowClient = mock(AirflowClient.class); private final SlackBotClient slackBotClient = mock(SlackBotClient.class); @@ -46,14 +46,19 @@ public class JitServiceImplTest { private final RoleService roleService = mock(RoleService.class); private final TeamService teamService = mock(TeamService.class); private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory()); - private final ResourceReaderUtil resourceReaderUtil = new ResourceReaderUtil(yamlMapper); + private final String requestConfigPath = "classpath:jit"; + private final Map> approvalMapProvider = + new ApprovalMapProvider(mapUtil, yamlMapper, requestConfigPath).additionalApprovalMap(); JitServiceImpl jitServiceImpl = new JitServiceImpl(jitRequestRepository, jitApprovalsRepository, slackBotUtil, mapUtil, authUtil, airflowClient, slackBotClient, objectMapper, userService, - roleService, teamService, yamlMapper, null, "classpath:jit", "null"); + roleService, teamService, approvalMapProvider, "null", "null"); User requestedFor = new User(); User requestedBy = new User(); + + JitRequestDto jitRequestDto = new JitRequestDto("alpha@one.com", "beta@two.com", Vertical.NAVIPAY, "Infra", Environment.PROD, "RDS", "dev-db", "read", 1L, null); @@ -61,14 +66,22 @@ public class JitServiceImplTest { @Test public void testCreateJitRequest() throws IOException { // Arrange + User additionalUser = new User(); + List teams = List.of( + new Team("Security") + ); + additionalUser.setTeams(teams); + additionalUser.setEmail("additional@one.com"); + + when(userService.findUserByEmail("additional@one.com")).thenReturn(additionalUser); + requestedFor.setEmail("alpha@one.com"); requestedBy.setEmail("beta@two.com"); when(userService.findUserByEmail("alpha@one.com")).thenReturn(requestedFor); when(userService.findUserByEmail("beta@two.com")).thenReturn(requestedBy); JitRequest jitRequestWithId = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, - List.of(new Team("Infra")), Environment.PROD, "RDS", "dev-db", "read", - JitRequestStatus.PENDING, + new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, 1L, LocalDateTime.now()); jitRequestWithId.setId(1L); when(jitRequestRepository.save(any())).thenReturn(jitRequestWithId); @@ -77,19 +90,22 @@ public class JitServiceImplTest { reviewerOne.setEmail("charlie@three.com"); User reviewerTwo = new User(); reviewerTwo.setEmail("delte@four.com"); + List reviewers = List.of(reviewerOne, reviewerTwo); - when(authUtil.getReviewers(jitRequestWithId)).thenReturn(reviewers); + when(authUtil.getReviewers(jitRequestWithId.getTeam().getName(), + jitRequestWithId.getEnvironment().type)).thenReturn(reviewers); + when(authUtil.getReviewers(additionalUser.getTeams().get(0).getName(), + jitRequestWithId.getEnvironment().type)).thenReturn(reviewers); JitRequest jitRequest = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, - List.of(new Team("Infra")), Environment.PROD, "RDS", "dev-db", "read", - JitRequestStatus.PENDING, + new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, 1L, LocalDateTime.now()); - JitApproval jitApprovalOne = new JitApproval(jitRequest, reviewerOne, + JitApproval jitApprovalOne = new JitApproval(jitRequest, reviewerOne, jitRequest.getTeam(), JitRequestStatus.PENDING); JitApproval jitApprovalOneWithId = jitApprovalOne; jitApprovalOneWithId.setId(1L); jitApprovalOneWithId.setReviewerSlackMessageTimestamp("132413513"); - JitApproval jitApprovalTwo = new JitApproval(jitRequest, reviewerTwo, + JitApproval jitApprovalTwo = new JitApproval(jitRequest, reviewerTwo, jitRequest.getTeam(), JitRequestStatus.PENDING); JitApproval jitApprovalTwoWithId = jitApprovalTwo; jitApprovalTwoWithId.setId(1L); @@ -97,7 +113,7 @@ public class JitServiceImplTest { List jitApprovals = List.of(jitApprovalOne, jitApprovalTwo); List jitApprovalsWithId = List.of(jitApprovalOneWithId, jitApprovalTwoWithId); - when(teamService.findByNames(List.of("Infra"))).thenReturn(List.of(new Team("Infra"))); + when(teamService.findByName("Infra")).thenReturn(new Team("Infra")); when(userService.getUsersSlackId(jitRequest.getRequestedFor())).thenReturn("U12314"); when(slackBotClient.postMessage(any(), any())).thenReturn("2341419824719"); when(jitApprovalsRepository.saveAll(jitApprovals)).thenReturn(jitApprovalsWithId); diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java index aedc7b2c..3ef3a891 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -8,14 +8,17 @@ import com.navi.infra.portal.domain.user.Role; import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; +import com.navi.infra.portal.v2.jit.dto.JitRequestDto; import com.navi.infra.portal.v2.jit.entity.Environment; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; import com.navi.infra.portal.v2.role.RoleService; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.Assert; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.test.util.ReflectionTestUtils; @@ -41,7 +44,7 @@ public class AuthUtilTest { @DisplayName("Check if the user authorized and has specific role") public void testIsAuthorized() { JitRequest jitRequest = new JitRequest(); - jitRequest.setTeams(List.of(new Team("Infra"))); + jitRequest.setTeam(new Team("Infra")); jitRequest.setEnvironment(Environment.PROD); String testEmail = "alpha@one.com"; User testUser = new User(); @@ -50,7 +53,7 @@ public class AuthUtilTest { testUser.setRoles(mockRoles); when(userService.findUserByEmail(testEmail)).thenReturn(testUser); - assertTrue(authUtil.isAuthorized(testEmail, jitRequest)); + assertTrue(authUtil.isAuthorized(testEmail, jitRequest, Collections.emptyList())); } @Test @@ -77,7 +80,7 @@ public class AuthUtilTest { ReflectionTestUtils.setField(authUtil, "prodJitApprovalsCount", 2L); - when(jitApprovalsRepository.findApprovedRequestsCount(jitRequest.getId())) + when(jitApprovalsRepository.findTotalApprovalsIfAllTeamsApproved(jitRequest.getId())) .thenReturn(2L); boolean result = authUtil.haveRequiredApprovals(jitRequest); @@ -93,37 +96,38 @@ public class AuthUtilTest { ReflectionTestUtils.setField(authUtil, "nonprodJitApprovalsCount", 1L); - when(jitApprovalsRepository.findApprovedRequestsCount(jitRequest.getId())) + when(jitApprovalsRepository.findTotalApprovalsIfAllTeamsApproved(jitRequest.getId())) .thenReturn(1L); boolean result = authUtil.haveRequiredApprovals(jitRequest); Assert.assertTrue(result); } -// @Test -// @DisplayName("Should be able to get reviewers for certain combination of team and environment") -// public void testGetReviewers() { -// JitRequestDto mockRequestDto = new JitRequestDto(); -// mockRequestDto.setTeam("Infra"); -// mockRequestDto.setEnvironment(Environment.DEV); -// -// User reviewer1 = new User(); -// reviewer1.setEmail("reviewer1@domain.com"); -// User reviewer2 = new User(); -// reviewer2.setEmail("reviewer2@domain.com"); -// List specificRoleReviewers = new ArrayList<>(List.of(reviewer1)); -// List allReviewers = List.of(reviewer2); -// -// when(userService.getUsersWithRole("Infra_dev_JITREVIEWER")) -// .thenReturn(specificRoleReviewers); -// when(userService.getUsersWithRole("Infra_ALL_JITREVIEWER")) -// .thenReturn(allReviewers); -// -// List result = authUtil.getReviewers(mockRequestDto); -// -// Assertions.assertEquals(2, result.size()); -// Assertions.assertTrue(result.contains(reviewer1)); -// Assertions.assertTrue(result.contains(reviewer2)); -// } + @Test + @DisplayName("Should be able to get reviewers for certain combination of team and environment") + public void testGetReviewers() { + JitRequestDto mockRequestDto = new JitRequestDto(); + mockRequestDto.setTeam("Infra"); + mockRequestDto.setEnvironment(Environment.DEV); + + User reviewer1 = new User(); + reviewer1.setEmail("reviewer1@domain.com"); + User reviewer2 = new User(); + reviewer2.setEmail("reviewer2@domain.com"); + List specificRoleReviewers = new ArrayList<>(List.of(reviewer1)); + List allReviewers = List.of(reviewer2); + + when(userService.getUsersWithRole("Infra_dev_JITREVIEWER")) + .thenReturn(specificRoleReviewers); + when(userService.getUsersWithRole("Infra_ALL_JITREVIEWER")) + .thenReturn(allReviewers); + + List result = authUtil.getReviewers(mockRequestDto.getTeam(), + mockRequestDto.getEnvironment().type); + + Assertions.assertEquals(2, result.size()); + Assertions.assertTrue(result.contains(reviewer1)); + Assertions.assertTrue(result.contains(reviewer2)); + } } diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java index 111c63ed..a8c1e279 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java @@ -10,7 +10,6 @@ import com.navi.infra.portal.v2.jit.entity.Vertical; import com.navi.infra.portal.v2.slackbotclient.SlackBotAttachment; import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -20,7 +19,7 @@ public class SlackBotUtilTest { String userEmail = "test@domain.com"; JitRequest jitRequest = new JitRequest(new User(), new User(), Vertical.SA, - List.of(new Team("Infra")), Environment.DEV, "RDS", "dev-db", + new Team("Infra"), Environment.DEV, "RDS", "dev-db", "read", JitRequestStatus.PENDING, 5L, LocalDateTime.now()); JitApproval jitApproval = new JitApproval(); From 903942f740fae304bd4ee30a4e7cd498ec53de4f Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Fri, 26 Apr 2024 14:35:47 +0530 Subject: [PATCH 078/108] INFRA-3188 | Dhruv | remove comment --- src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java | 1 - .../java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 979f2622..5262f5a6 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -81,7 +81,6 @@ public class AuthUtil { return userService.getUsersWithRole(reviewerRole.getName()); } - // public List public List getReviewers(String teamName, String environmentType) { // Determine the reviewers based on REQUEST List environmentSpecificReviewers = getReviewersFromRole(teamName, environmentType); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index ff58026d..006a59a2 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -152,7 +152,6 @@ public class SlackBotUtil { public SlackBotAttachment getRequestorRequestNotAllowedDm( JitRequest jitRequest ) { - // TODO: No placeholder for team names :| SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format( "Request for same resource in the specified window already exists. " From 7bba81c42d466ce2defb7e44420a0a7c11cf52a6 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 26 Apr 2024 15:42:02 +0530 Subject: [PATCH 079/108] INFRA-2743 | Harinder | Updating tests for kutegen changes: Loading environment variables using EnvFrom rather than Env to reduce the size of manifest --- .../kube_objects/kube_object_alb.json | 25 ++++++------------- .../kube_object_alb_redirect.json | 25 ++++++------------- .../kube_objects/kube_object_efs_pvc.json | 25 ++++++------------- .../kube_objects/kube_object_fsx.json | 25 ++++++------------- .../kube_objects/kube_object_prod_tsc.json | 16 ++++++------ .../kube_object_prod_with_maxsurge.json | 16 ++++++------ 6 files changed, 42 insertions(+), 90 deletions(-) diff --git a/src/test/resources/fixtures/kube_objects/kube_object_alb.json b/src/test/resources/fixtures/kube_objects/kube_object_alb.json index 2cd0f35c..cbe99558 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_alb.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_alb.json @@ -238,29 +238,18 @@ } }, "env": [ - { - "name": "password", - "valueFrom": { - "secretKeyRef": { - "name": "test-app-navi-service-secret", - "key": "password" - } - } - }, - { - "name": "user", - "valueFrom": { - "secretKeyRef": { - "name": "test-app-navi-service-secret", - "key": "user" - } - } - }, { "name": "secretMd5", "value": "d74618e323ae5b8a83fa496eb16ef003" } ], + "envFrom": [ + { + "secretRef": { + "name": "test-app-navi-service-secret" + } + } + ], "ports": [ { "protocol": "TCP", diff --git a/src/test/resources/fixtures/kube_objects/kube_object_alb_redirect.json b/src/test/resources/fixtures/kube_objects/kube_object_alb_redirect.json index fbabe090..0cd180ec 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_alb_redirect.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_alb_redirect.json @@ -222,29 +222,18 @@ } }, "env": [ - { - "name": "password", - "valueFrom": { - "secretKeyRef": { - "name": "test-app-navi-service-secret", - "key": "password" - } - } - }, - { - "name": "user", - "valueFrom": { - "secretKeyRef": { - "name": "test-app-navi-service-secret", - "key": "user" - } - } - }, { "name": "secretMd5", "value": "d74618e323ae5b8a83fa496eb16ef003" } ], + "envFrom": [ + { + "secretRef": { + "name": "test-app-navi-service-secret" + } + } + ], "ports": [ { "protocol": "TCP", diff --git a/src/test/resources/fixtures/kube_objects/kube_object_efs_pvc.json b/src/test/resources/fixtures/kube_objects/kube_object_efs_pvc.json index cdd6b1fb..d4278932 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_efs_pvc.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_efs_pvc.json @@ -205,29 +205,18 @@ "containers": [ { "env": [ - { - "name": "password", - "valueFrom": { - "secretKeyRef": { - "key": "password", - "name": "test-app-navi-service-secret" - } - } - }, - { - "name": "user", - "valueFrom": { - "secretKeyRef": { - "key": "user", - "name": "test-app-navi-service-secret" - } - } - }, { "name": "secretMd5", "value": "d74618e323ae5b8a83fa496eb16ef003" } ], + "envFrom": [ + { + "secretRef": { + "name": "test-app-navi-service-secret" + } + } + ], "image": "IMAGE", "imagePullPolicy": "IfNotPresent", "lifecycle": { diff --git a/src/test/resources/fixtures/kube_objects/kube_object_fsx.json b/src/test/resources/fixtures/kube_objects/kube_object_fsx.json index 2c690432..a18b990c 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_fsx.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_fsx.json @@ -205,29 +205,18 @@ "containers": [ { "env": [ - { - "name": "password", - "valueFrom": { - "secretKeyRef": { - "key": "password", - "name": "test-app-navi-service-secret" - } - } - }, - { - "name": "user", - "valueFrom": { - "secretKeyRef": { - "key": "user", - "name": "test-app-navi-service-secret" - } - } - }, { "name": "secretMd5", "value": "d74618e323ae5b8a83fa496eb16ef003" } ], + "envFrom": [ + { + "secretRef": { + "name": "test-app-navi-service-secret" + } + } + ], "image": "IMAGE", "imagePullPolicy": "IfNotPresent", "lifecycle": { diff --git a/src/test/resources/fixtures/kube_objects/kube_object_prod_tsc.json b/src/test/resources/fixtures/kube_objects/kube_object_prod_tsc.json index de774c99..36123813 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_prod_tsc.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_prod_tsc.json @@ -231,20 +231,18 @@ } }, "env": [ - { - "name": "foo", - "valueFrom": { - "secretKeyRef": { - "name": "testapp-navi-service-secret", - "key": "foo" - } - } - }, { "name": "secretMd5", "value": "8a40bdadb732b9107fbf1eba768a302a" } ], + "envFrom": [ + { + "secretRef": { + "name": "testapp-navi-service-secret" + } + } + ], "ports": [ { "protocol": "TCP", diff --git a/src/test/resources/fixtures/kube_objects/kube_object_prod_with_maxsurge.json b/src/test/resources/fixtures/kube_objects/kube_object_prod_with_maxsurge.json index 82e1055f..d7794281 100644 --- a/src/test/resources/fixtures/kube_objects/kube_object_prod_with_maxsurge.json +++ b/src/test/resources/fixtures/kube_objects/kube_object_prod_with_maxsurge.json @@ -231,20 +231,18 @@ } }, "env": [ - { - "name": "foo", - "valueFrom": { - "secretKeyRef": { - "name": "testapp-navi-service-secret", - "key": "foo" - } - } - }, { "name": "secretMd5", "value": "8a40bdadb732b9107fbf1eba768a302a" } ], + "envFrom": [ + { + "secretRef": { + "name": "testapp-navi-service-secret" + } + } + ], "ports": [ { "protocol": "TCP", From 9b78fb1b234e781d60385ed808ed3e410fcc63d6 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Fri, 26 Apr 2024 16:01:54 +0530 Subject: [PATCH 080/108] INFRA-2743 | Harinder | Updating kutegen because of env and envfrom changes --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 2054ce08..117543e6 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 2054ce084d5c53b3a50cc3c1e3d856f6af177e89 +Subproject commit 117543e69537fbfa37917ec6af5087c13307638e From f23f095ae1184a5cf402d9cf0ef7fba6ab14ddf4 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Sun, 28 Apr 2024 12:15:37 +0530 Subject: [PATCH 081/108] INFRA-3188 | Dhruv | add test and fix yaml --- .../portal/v2/jit/service/JitServiceImpl.java | 21 ++- src/main/resources/jit/{dev.yaml => cmd.yaml} | 45 +++--- .../{pref.yaml => data-platform-prod.yaml} | 45 +++--- src/main/resources/jit/default.yaml | 47 ++---- src/main/resources/jit/prod.yaml | 45 +++--- src/main/resources/jit/qa.yaml | 53 ------- .../v2/jit/service/JitServiceImplTest.java | 150 ++++++++++++------ 7 files changed, 179 insertions(+), 227 deletions(-) rename src/main/resources/jit/{dev.yaml => cmd.yaml} (67%) rename src/main/resources/jit/{pref.yaml => data-platform-prod.yaml} (67%) delete mode 100644 src/main/resources/jit/qa.yaml diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index cdb4258b..15ac6133 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -362,11 +362,18 @@ class JitServiceImpl implements JitService { ) { String jsonPath = String.format("/resources/%s/%s/approvalFrom", resourceType, resourceAction); - var result = mapUtil.getValueAtPath(additionalApprovalMap.get(env), jsonPath); - if (result instanceof List) { - return (List) result; + try { + return Optional.ofNullable( + mapUtil.getValueAtPath(additionalApprovalMap.get(env), jsonPath)) + .filter(List.class::isInstance) + .map(result -> (List) result) + .orElseGet(ArrayList::new); + } catch (NullPointerException | IllegalStateException e) { + log.warn( + "Can't fetch additional approval list for : {}/{}/{}, error: {}", + env, resourceAction, resourceAction, e.getMessage()); + return new ArrayList<>(); } - return new ArrayList<>(); } private Map> getAdditionalTeamsAndReviewer( @@ -429,16 +436,16 @@ class JitServiceImpl implements JitService { jitRequest.getEnvironment().type, jitRequest.getRequestedFor().getEmail() ); - var teamsWithoutUsers = additionalTeamReviewers.entrySet().stream() + var teamsWithoutReviewers = additionalTeamReviewers.entrySet().stream() .filter(entry -> entry.getValue().isEmpty()) .map(Map.Entry::getKey) .collect(Collectors.toList()); - if (!teamsWithoutUsers.isEmpty()) { + if (!teamsWithoutReviewers.isEmpty()) { // no reviwers found for additional teams, inform user updateRequestorNoReviewersDmOnSlack(jitRequest); throw new IllegalStateException( - "No reviewers found for additional teams : " + teamsWithoutUsers.stream() + "No reviewers found for additional teams : " + teamsWithoutReviewers.stream() .map(Team::getName).collect(Collectors.joining(","))); } diff --git a/src/main/resources/jit/dev.yaml b/src/main/resources/jit/cmd.yaml similarity index 67% rename from src/main/resources/jit/dev.yaml rename to src/main/resources/jit/cmd.yaml index 0fff4ab7..33cd2e55 100644 --- a/src/main/resources/jit/dev.yaml +++ b/src/main/resources/jit/cmd.yaml @@ -1,53 +1,44 @@ resources: AWS: - master: - approvalFrom: - - Security - - Infra read: approvalFrom: - Security - - Infra - admin: + write: approvalFrom: - Security - - Infra - RDS: master: approvalFrom: - Security - - Infra + manager: + approvalFrom: + - Security + KUBERNETES: read: approvalFrom: - Security - - Infra - admin: + write: approvalFrom: - Security - - Infra - K8S: master: approvalFrom: - Security - - Infra - read: + - Architect + manager: approvalFrom: - Security - - Infra - admin: - approvalFrom: - - Security - - Infra + - Architect DB: - master: - approvalFrom: - - Security - - Infra read: approvalFrom: - Security - - Infra - admin: + write: approvalFrom: - Security - - Infra \ No newline at end of file + master: + approvalFrom: + - Security + - Architect + manager: + approvalFrom: + - Security + - Architect \ No newline at end of file diff --git a/src/main/resources/jit/pref.yaml b/src/main/resources/jit/data-platform-prod.yaml similarity index 67% rename from src/main/resources/jit/pref.yaml rename to src/main/resources/jit/data-platform-prod.yaml index 0fff4ab7..33cd2e55 100644 --- a/src/main/resources/jit/pref.yaml +++ b/src/main/resources/jit/data-platform-prod.yaml @@ -1,53 +1,44 @@ resources: AWS: - master: - approvalFrom: - - Security - - Infra read: approvalFrom: - Security - - Infra - admin: + write: approvalFrom: - Security - - Infra - RDS: master: approvalFrom: - Security - - Infra + manager: + approvalFrom: + - Security + KUBERNETES: read: approvalFrom: - Security - - Infra - admin: + write: approvalFrom: - Security - - Infra - K8S: master: approvalFrom: - Security - - Infra - read: + - Architect + manager: approvalFrom: - Security - - Infra - admin: - approvalFrom: - - Security - - Infra + - Architect DB: - master: - approvalFrom: - - Security - - Infra read: approvalFrom: - Security - - Infra - admin: + write: approvalFrom: - Security - - Infra \ No newline at end of file + master: + approvalFrom: + - Security + - Architect + manager: + approvalFrom: + - Security + - Architect \ No newline at end of file diff --git a/src/main/resources/jit/default.yaml b/src/main/resources/jit/default.yaml index 0fff4ab7..346bd5d3 100644 --- a/src/main/resources/jit/default.yaml +++ b/src/main/resources/jit/default.yaml @@ -1,53 +1,28 @@ resources: AWS: - master: - approvalFrom: - - Security - - Infra read: approvalFrom: - - Security - - Infra - admin: + write: approvalFrom: - - Security - - Infra - RDS: master: approvalFrom: - - Security - - Infra + manager: + approvalFrom: + KUBERNETES: read: approvalFrom: - - Security - - Infra - admin: + write: approvalFrom: - - Security - - Infra - K8S: master: approvalFrom: - - Security - - Infra - read: + manager: approvalFrom: - - Security - - Infra - admin: - approvalFrom: - - Security - - Infra DB: - master: - approvalFrom: - - Security - - Infra read: approvalFrom: - - Security - - Infra - admin: + write: + approvalFrom: + master: + approvalFrom: + manager: approvalFrom: - - Security - - Infra \ No newline at end of file diff --git a/src/main/resources/jit/prod.yaml b/src/main/resources/jit/prod.yaml index 0fff4ab7..33cd2e55 100644 --- a/src/main/resources/jit/prod.yaml +++ b/src/main/resources/jit/prod.yaml @@ -1,53 +1,44 @@ resources: AWS: - master: - approvalFrom: - - Security - - Infra read: approvalFrom: - Security - - Infra - admin: + write: approvalFrom: - Security - - Infra - RDS: master: approvalFrom: - Security - - Infra + manager: + approvalFrom: + - Security + KUBERNETES: read: approvalFrom: - Security - - Infra - admin: + write: approvalFrom: - Security - - Infra - K8S: master: approvalFrom: - Security - - Infra - read: + - Architect + manager: approvalFrom: - Security - - Infra - admin: - approvalFrom: - - Security - - Infra + - Architect DB: - master: - approvalFrom: - - Security - - Infra read: approvalFrom: - Security - - Infra - admin: + write: approvalFrom: - Security - - Infra \ No newline at end of file + master: + approvalFrom: + - Security + - Architect + manager: + approvalFrom: + - Security + - Architect \ No newline at end of file diff --git a/src/main/resources/jit/qa.yaml b/src/main/resources/jit/qa.yaml deleted file mode 100644 index 0fff4ab7..00000000 --- a/src/main/resources/jit/qa.yaml +++ /dev/null @@ -1,53 +0,0 @@ -resources: - AWS: - master: - approvalFrom: - - Security - - Infra - read: - approvalFrom: - - Security - - Infra - admin: - approvalFrom: - - Security - - Infra - RDS: - master: - approvalFrom: - - Security - - Infra - read: - approvalFrom: - - Security - - Infra - admin: - approvalFrom: - - Security - - Infra - K8S: - master: - approvalFrom: - - Security - - Infra - read: - approvalFrom: - - Security - - Infra - admin: - approvalFrom: - - Security - - Infra - DB: - master: - approvalFrom: - - Security - - Infra - read: - approvalFrom: - - Security - - Infra - admin: - approvalFrom: - - Security - - Infra \ No newline at end of file diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java index d38d31f7..f2c4f37c 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -1,7 +1,9 @@ package com.navi.infra.portal.v2.jit.service; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.fasterxml.jackson.databind.ObjectMapper; @@ -29,62 +31,83 @@ import java.io.IOException; import java.time.LocalDateTime; import java.util.List; import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +@ExtendWith(MockitoExtension.class) class JitServiceImplTest { - private final JitRequestsRepository jitRequestRepository = mock(JitRequestsRepository.class); - private final JitApprovalsRepository jitApprovalsRepository = mock( - JitApprovalsRepository.class); - private final SlackBotUtil slackBotUtil = mock(SlackBotUtil.class); - private final AuthUtil authUtil = mock(AuthUtil.class); - private final MapUtil mapUtil = new MapUtil(); - private final AirflowClient airflowClient = mock(AirflowClient.class); - private final SlackBotClient slackBotClient = mock(SlackBotClient.class); - - private final UserService userService = mock(UserService.class); - private final RoleService roleService = mock(RoleService.class); - private final TeamService teamService = mock(TeamService.class); private final ObjectMapper objectMapper = new ObjectMapper(); - private final ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory()); - private final String requestConfigPath = "classpath:jit"; + private final MapUtil mapUtil = new MapUtil(); private final Map> approvalMapProvider = new ApprovalMapProvider(mapUtil, yamlMapper, requestConfigPath).additionalApprovalMap(); - JitServiceImpl jitServiceImpl = new JitServiceImpl(jitRequestRepository, jitApprovalsRepository, - slackBotUtil, mapUtil, authUtil, airflowClient, slackBotClient, objectMapper, userService, - roleService, teamService, approvalMapProvider, "null", "null"); - User requestedFor = new User(); - User requestedBy = new User(); + JitServiceImpl jitServiceImpl; + private User requestedFor; + private User requestedBy; + private JitRequestDto jitRequestDto; + private JitRequest jitRequestWithId; + @Mock + private JitRequestsRepository jitRequestRepository; + @Mock + private JitApprovalsRepository jitApprovalsRepository; + @Mock + private SlackBotUtil slackBotUtil; + @Mock + private AuthUtil authUtil; + @Mock + private AirflowClient airflowClient; + @Mock + private SlackBotClient slackBotClient; + @Mock + private UserService userService; + @Mock + private RoleService roleService; + @Mock + private TeamService teamService; - JitRequestDto jitRequestDto = new JitRequestDto("alpha@one.com", "beta@two.com", - Vertical.NAVIPAY, "Infra", Environment.PROD, "RDS", "dev-db", "read", 1L, null); + @BeforeEach + void setUp() { + jitServiceImpl = new JitServiceImpl(jitRequestRepository, + jitApprovalsRepository, + slackBotUtil, mapUtil, authUtil, airflowClient, slackBotClient, objectMapper, + userService, + roleService, teamService, approvalMapProvider, "null", "null"); + requestedFor = new User(); + requestedBy = new User(); + requestedFor.setEmail("alpha@one.com"); + requestedBy.setEmail("beta@two.com"); + when(userService.findUserByEmail("alpha@one.com")).thenReturn(requestedFor); + when(userService.findUserByEmail("beta@two.com")).thenReturn(requestedBy); + when(teamService.findByName("Infra")).thenReturn(new Team("Infra")); + + jitRequestDto = new JitRequestDto("alpha@one.com", "beta@two.com", + Vertical.NAVIPAY, "Infra", Environment.PROD, "DB", "dev-db", + "read", 1L, null); + jitRequestWithId = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, + new Team("Infra"), Environment.PROD, "DB", "dev-db", "read", JitRequestStatus.PENDING, + 1L, LocalDateTime.now()); + jitRequestWithId.setId(1L); + } @Test public void testCreateJitRequest() throws IOException { // Arrange User additionalUser = new User(); - List teams = List.of( + List additionalUserTeams = List.of( new Team("Security") ); - additionalUser.setTeams(teams); + additionalUser.setTeams(additionalUserTeams); additionalUser.setEmail("additional@one.com"); - when(userService.findUserByEmail("additional@one.com")).thenReturn(additionalUser); - - requestedFor.setEmail("alpha@one.com"); - requestedBy.setEmail("beta@two.com"); - when(userService.findUserByEmail("alpha@one.com")).thenReturn(requestedFor); - when(userService.findUserByEmail("beta@two.com")).thenReturn(requestedBy); - - JitRequest jitRequestWithId = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, - new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, - 1L, LocalDateTime.now()); - jitRequestWithId.setId(1L); - when(jitRequestRepository.save(any())).thenReturn(jitRequestWithId); + when(teamService.findByName("Security")).thenReturn(additionalUserTeams.get(0)); User reviewerOne = new User(); reviewerOne.setEmail("charlie@three.com"); @@ -94,31 +117,58 @@ class JitServiceImplTest { List reviewers = List.of(reviewerOne, reviewerTwo); when(authUtil.getReviewers(jitRequestWithId.getTeam().getName(), jitRequestWithId.getEnvironment().type)).thenReturn(reviewers); - when(authUtil.getReviewers(additionalUser.getTeams().get(0).getName(), - jitRequestWithId.getEnvironment().type)).thenReturn(reviewers); + when(authUtil.getReviewers(additionalUserTeams.get(0).getName(), + jitRequestWithId.getEnvironment().type)).thenReturn(List.of(additionalUser)); JitRequest jitRequest = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, - new Team("Infra"), Environment.PROD, "RDS", "dev-db", "read", JitRequestStatus.PENDING, + new Team("Infra"), Environment.PROD, "DB", "dev-db", "read", JitRequestStatus.PENDING, 1L, LocalDateTime.now()); JitApproval jitApprovalOne = new JitApproval(jitRequest, reviewerOne, jitRequest.getTeam(), JitRequestStatus.PENDING); - JitApproval jitApprovalOneWithId = jitApprovalOne; - jitApprovalOneWithId.setId(1L); - jitApprovalOneWithId.setReviewerSlackMessageTimestamp("132413513"); + jitApprovalOne.setId(1L); + jitApprovalOne.setReviewerSlackMessageTimestamp("132413513"); + JitApproval jitApprovalTwo = new JitApproval(jitRequest, reviewerTwo, jitRequest.getTeam(), JitRequestStatus.PENDING); - JitApproval jitApprovalTwoWithId = jitApprovalTwo; - jitApprovalTwoWithId.setId(1L); - jitApprovalTwoWithId.setReviewerSlackMessageTimestamp("132413513"); - List jitApprovals = List.of(jitApprovalOne, jitApprovalTwo); - List jitApprovalsWithId = List.of(jitApprovalOneWithId, jitApprovalTwoWithId); + jitApprovalTwo.setId(2L); + jitApprovalTwo.setReviewerSlackMessageTimestamp("132413513"); - when(teamService.findByName("Infra")).thenReturn(new Team("Infra")); + JitApproval additionalJitApproval = new JitApproval(jitRequest, additionalUser, + additionalUserTeams.get(0), JitRequestStatus.PENDING); + additionalJitApproval.setId(3L); + additionalJitApproval.setReviewerSlackMessageTimestamp("132413513"); + + List jitApprovalsWithId = List.of(jitApprovalOne, jitApprovalTwo, + additionalJitApproval); + + when(jitRequestRepository.save(any())).thenReturn(jitRequestWithId); when(userService.getUsersSlackId(jitRequest.getRequestedFor())).thenReturn("U12314"); when(slackBotClient.postMessage(any(), any())).thenReturn("2341419824719"); - when(jitApprovalsRepository.saveAll(jitApprovals)).thenReturn(jitApprovalsWithId); - when(jitRequestRepository.save(jitRequest)).thenReturn(jitRequest); + when(jitApprovalsRepository.saveAll(any())).thenReturn(jitApprovalsWithId); jitServiceImpl.createJitRequest(jitRequestDto); + verify(jitRequestRepository, times(2)).save(any()); + verify(jitApprovalsRepository, times(1)).saveAll(any()); + + } + + @Test + @DisplayName("Should not be able to create JIT request if no reviewer for additional teams") + public void testCreateJitRequestWithNoAdditionalReviewers() throws IOException { + JitRequest jitRequest = new JitRequest(requestedFor, requestedBy, Vertical.NAVIPAY, + new Team("Infra"), Environment.PROD, "DB", "dev-db", "read", JitRequestStatus.PENDING, + 1L, LocalDateTime.now()); + User reviewerOne = new User(); + reviewerOne.setEmail("charlie@three.com"); + when(teamService.findByName("Security")).thenReturn(new Team("Security")); + + List reviewers = List.of(reviewerOne); + when(authUtil.getReviewers(jitRequestWithId.getTeam().getName(), + jitRequestWithId.getEnvironment().type)).thenReturn(reviewers); + when(userService.getUsersSlackId(jitRequest.getRequestedFor())).thenReturn("U12314"); + when(slackBotClient.postMessage(any(), any())).thenReturn("2341419824719"); + assertThrows(IllegalStateException.class, () -> { + jitServiceImpl.createJitRequest(jitRequestDto); + }); } } From 75d494ab42b21e2a8817766e2e5968f2e4355d1a Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Mon, 29 Apr 2024 14:46:34 +0530 Subject: [PATCH 082/108] INFRA-3188 | Dhruv | fix isAuthorized flow --- .../portal/v2/jit/service/JitServiceImpl.java | 6 +-- .../infra/portal/v2/jit/utils/AuthUtil.java | 40 ++++++++++++------- .../v2/jit/service/JitServiceImplTest.java | 1 - .../portal/v2/jit/utils/AuthUtilTest.java | 9 ++++- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 15ac6133..9872eef8 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -225,12 +225,8 @@ class JitServiceImpl implements JitService { throw new IllegalStateException("Request already reviewed"); } jitApproval.setReviewedAt(LocalDateTime.now()); - var additionalApprovalTeams = getAdditionalApprovalTeams( - jitRequest.getEnvironment().type, - jitRequest.getResourceType(), jitRequest.getResourceAction()); - if (!reviewerEmail.equals(jitApproval.getReviewer().getEmail()) - || !authUtil.isAuthorized(reviewerEmail, jitRequest, additionalApprovalTeams) + if (!authUtil.isAuthorized(jitApproval, reviewerEmail, jitRequest.getEnvironment().type) || reviewerEmail.equals(jitRequest.getRequestedFor().getEmail())) { log.error("User {} not allowed to perform action", reviewerEmail); throw new IllegalAccessException("User not allowed to perform action"); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 5262f5a6..d3201634 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -6,11 +6,11 @@ import com.navi.infra.portal.domain.user.Role; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; import com.navi.infra.portal.v2.jit.entity.Environment; +import com.navi.infra.portal.v2.jit.entity.JitApproval; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; import com.navi.infra.portal.v2.role.RoleService; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -34,26 +34,36 @@ public class AuthUtil { private Long nonprodJitApprovalsCount; + public boolean hasTeamApprovalAccess( + List userRoles, + String teamName, + String environmentType + ) { + return userRoles.stream() + .filter(role -> role.contains(JITREVIEWER.toString()) && role.contains(teamName)) + .anyMatch(role -> role.contains(environmentType) || role.contains("ALL")); + } + + public boolean hasPortalApprovalAccess(List userRoles) { + return userRoles.stream() + .anyMatch(role -> role.contains(JITREVIEWER.toString()) && role.contains("PORTAL")); + } + + public boolean isReviewer(String userEmail, JitApproval approvalRequest) { + return approvalRequest.getReviewer().getEmail().equals(userEmail); + } + public boolean isAuthorized( + JitApproval approvalRequest, String userEmail, - JitRequest jitRequest, - List additionalTeams + String environmentType ) { User user = userService.findUserByEmail(userEmail); List userRoles = user.getRoles().stream().map(Role::getName) .collect(Collectors.toList()); - - var allTeams = new ArrayList(); - allTeams.add(jitRequest.getTeam().getName()); - allTeams.addAll(additionalTeams); - - return userRoles.stream() - .filter(role -> role.contains(JITREVIEWER.toString()) - && allTeams.stream().anyMatch(role::contains) - || role.contains("PORTAL")) - .anyMatch(role -> role.contains(jitRequest.getEnvironment().type) - || role.contains("ALL") - || role.contains("PORTAL")); + return isReviewer(userEmail, approvalRequest) && hasTeamApprovalAccess(userRoles, + approvalRequest.getTeam().getName(), environmentType) + || hasPortalApprovalAccess(userRoles); } public List getReviewersByAction( diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java index f2c4f37c..ed6fd76d 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -54,7 +54,6 @@ class JitServiceImplTest { private JitRequest jitRequestWithId; @Mock private JitRequestsRepository jitRequestRepository; - @Mock private JitApprovalsRepository jitApprovalsRepository; @Mock diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java index 3ef3a891..5399701e 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -10,6 +10,7 @@ import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; import com.navi.infra.portal.v2.jit.dto.JitRequestDto; import com.navi.infra.portal.v2.jit.entity.Environment; +import com.navi.infra.portal.v2.jit.entity.JitApproval; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; @@ -51,9 +52,13 @@ public class AuthUtilTest { testUser.setEmail("alpha@one.com"); List mockRoles = Collections.singletonList(new Role("Infra_prod_JITREVIEWER")); testUser.setRoles(mockRoles); - when(userService.findUserByEmail(testEmail)).thenReturn(testUser); + JitApproval jitApproval = new JitApproval(); + jitApproval.setReviewer(testUser); + jitApproval.setTeam(new Team("Infra")); + jitApproval.setAction(JitRequestStatus.PENDING); - assertTrue(authUtil.isAuthorized(testEmail, jitRequest, Collections.emptyList())); + when(userService.findUserByEmail(testEmail)).thenReturn(testUser); + assertTrue(authUtil.isAuthorized(jitApproval, testEmail, jitRequest.getEnvironment().type)); } @Test From 4b119a8d28275428289e94603601a0a76e0128bf Mon Sep 17 00:00:00 2001 From: Aviral Harsh Date: Mon, 29 Apr 2024 16:52:09 +0530 Subject: [PATCH 083/108] INFRA-3200 | Aviral | Adding cert entry for navifinserv.com --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 117543e6..c5f45680 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 117543e69537fbfa37917ec6af5087c13307638e +Subproject commit c5f456804ceea1d8c40412794f856a91602477bf From ea1e367b841de5ecd6ddea622acf89e3224c984f Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Mon, 29 Apr 2024 17:42:58 +0530 Subject: [PATCH 084/108] INFRA-3188 | Dhruv | fix pr comments --- .../navi/infra/portal/util/ResourceReaderUtil.java | 7 +++---- .../service/ManifestLimitServiceImpl.java | 12 +++++++++--- .../v2/jit/repository/JitApprovalsRepository.java | 12 +----------- .../portal/v2/jit/utils/ApprovalMapProvider.java | 12 +++++++++--- .../com/navi/infra/portal/v2/jit/utils/AuthUtil.java | 11 +++++++++-- .../navi/infra/portal/v2/jit/utils/AuthUtilTest.java | 8 ++++---- 6 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java b/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java index 30a1956f..349f26d1 100644 --- a/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java +++ b/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java @@ -25,8 +25,8 @@ public class ResourceReaderUtil { @SuppressWarnings("unchecked") public Map getResourceFromPath(List path) - throws RuntimeException { - Map map; + throws RuntimeException, FileNotFoundException { + Map map = emptyMap(); String pathString = String.join("/", path); try { final var fileInputStream = resourceLoader @@ -35,8 +35,7 @@ public class ResourceReaderUtil { map = objectMapper.readValue(fileInputStream, Map.class); } catch (FileNotFoundException e) { log.info("File is not found in path: {}", pathString); - map = emptyMap(); - throw new RuntimeException(e); + throw e; } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/main/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImpl.java index bba0db34..b72dd35e 100644 --- a/src/main/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/changerequest/service/ManifestLimitServiceImpl.java @@ -5,6 +5,7 @@ import static java.util.Collections.unmodifiableMap; import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.util.MapUtil; import com.navi.infra.portal.util.ResourceReaderUtil; +import java.io.FileNotFoundException; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Qualifier; @@ -33,13 +34,18 @@ public class ManifestLimitServiceImpl implements ManifestLimitService { @Override public Map getLimit(String env) { - var defaultLimitMap = resourceReaderUtil.getResourceFromPath( - List.of(changeRequestFilepath, "default.yaml")); + Map defaultLimitMap; + try { + defaultLimitMap = resourceReaderUtil.getResourceFromPath( + List.of(changeRequestFilepath, "default.yaml")); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } try { var envLimitMap = resourceReaderUtil.getResourceFromPath( List.of(changeRequestFilepath, vertical, env + ".yaml")); return unmodifiableMap(mapUtil.override(defaultLimitMap, envLimitMap)); - } catch (RuntimeException e) { + } catch (RuntimeException | FileNotFoundException e) { return unmodifiableMap(defaultLimitMap); } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java index 7edca74a..37a1f71a 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java @@ -27,17 +27,7 @@ public interface JitApprovalsRepository extends JpaRepository + "GROUP BY ja.team_id", nativeQuery = true) List countApprovedInEachTeam(Long jitId); - - default Long findTotalApprovalsIfAllTeamsApproved(Long jitId) { - List approvalList = countApprovedInEachTeam(jitId); - long totalApproved = approvalList.stream() - .mapToLong(Long::longValue) - .sum(); - boolean allTeamApproval = approvalList.stream() - .allMatch(approval -> approval >= 1); - return allTeamApproval ? totalApproved : 0; - } - + @Query(value = "SELECT ja.reviewer_id FROM jit_approvals ja " + "WHERE ja.jit_id = :jitId and ja.action = :action", nativeQuery = true) List findReviewersByAction(Long jitId, String action); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/ApprovalMapProvider.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/ApprovalMapProvider.java index b4376ad2..ccf6bac5 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/ApprovalMapProvider.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/ApprovalMapProvider.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.navi.infra.portal.util.MapUtil; import com.navi.infra.portal.util.ResourceReaderUtil; import com.navi.infra.portal.v2.jit.entity.Environment; +import java.io.FileNotFoundException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,13 +33,18 @@ public class ApprovalMapProvider { } public Map getAdditionalApprovalMap(String env) { - var defaultLimitMap = resourceReaderUtil.getResourceFromPath( - List.of(requestConfigPath, "default.yaml")); + Map defaultLimitMap; + try { + defaultLimitMap = resourceReaderUtil.getResourceFromPath( + List.of(requestConfigPath, "default.yaml")); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } try { var envLimitMap = resourceReaderUtil.getResourceFromPath( List.of(requestConfigPath, env + ".yaml")); return unmodifiableMap(mapUtil.override(defaultLimitMap, envLimitMap)); - } catch (RuntimeException e) { + } catch (RuntimeException | FileNotFoundException e) { return unmodifiableMap(defaultLimitMap); } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index d3201634..028d1c85 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -76,10 +76,17 @@ public class AuthUtil { .collect(Collectors.toList()); } + Long findTotalApprovalsIfAllTeamsApproved(Long jitId) { + List approvalList = jitApprovalsRepository.countApprovedInEachTeam(jitId); + long totalApproved = approvalList.stream().reduce(0L, Long::sum); + boolean allTeamApproval = approvalList.stream() + .allMatch(approval -> approval >= 1); + return allTeamApproval ? totalApproved : 0; + } + public boolean haveRequiredApprovals(JitRequest jitRequest) { Environment env = jitRequest.getEnvironment(); - Long approvedRequests = jitApprovalsRepository.findTotalApprovalsIfAllTeamsApproved( - jitRequest.getId()); + Long approvedRequests = findTotalApprovalsIfAllTeamsApproved(jitRequest.getId()); // is atleast one approval from each required team obtained based on the mapping in yaml // and required approval type (master or something) return approvedRequests >= env.approvals; diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java index 5399701e..d4a70a3a 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -85,8 +85,8 @@ public class AuthUtilTest { ReflectionTestUtils.setField(authUtil, "prodJitApprovalsCount", 2L); - when(jitApprovalsRepository.findTotalApprovalsIfAllTeamsApproved(jitRequest.getId())) - .thenReturn(2L); + when(jitApprovalsRepository.countApprovedInEachTeam(jitRequest.getId())) + .thenReturn(List.of(1L, 1L)); boolean result = authUtil.haveRequiredApprovals(jitRequest); Assert.assertTrue(result); @@ -101,8 +101,8 @@ public class AuthUtilTest { ReflectionTestUtils.setField(authUtil, "nonprodJitApprovalsCount", 1L); - when(jitApprovalsRepository.findTotalApprovalsIfAllTeamsApproved(jitRequest.getId())) - .thenReturn(1L); + when(jitApprovalsRepository.countApprovedInEachTeam(jitRequest.getId())) + .thenReturn(List.of(1L)); boolean result = authUtil.haveRequiredApprovals(jitRequest); Assert.assertTrue(result); From 96231b8c512ae953dd0221c656cf944d638e348f Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Mon, 29 Apr 2024 18:22:40 +0530 Subject: [PATCH 085/108] INFRA-3188 | Dhruv | remove unchecked exception from throws --- kutegen | 2 +- .../java/com/navi/infra/portal/util/ResourceReaderUtil.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/kutegen b/kutegen index c5f45680..2054ce08 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit c5f456804ceea1d8c40412794f856a91602477bf +Subproject commit 2054ce084d5c53b3a50cc3c1e3d856f6af177e89 diff --git a/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java b/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java index 349f26d1..5777ba92 100644 --- a/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java +++ b/src/main/java/com/navi/infra/portal/util/ResourceReaderUtil.java @@ -24,8 +24,7 @@ public class ResourceReaderUtil { } @SuppressWarnings("unchecked") - public Map getResourceFromPath(List path) - throws RuntimeException, FileNotFoundException { + public Map getResourceFromPath(List path) throws FileNotFoundException { Map map = emptyMap(); String pathString = String.join("/", path); try { From 5fcfac38212864cadedd100d4ca0d69d2b193d30 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Mon, 29 Apr 2024 18:58:27 +0530 Subject: [PATCH 086/108] INFRA-3188 | Dhruv | kutegen bump --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 2054ce08..c5f45680 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 2054ce084d5c53b3a50cc3c1e3d856f6af177e89 +Subproject commit c5f456804ceea1d8c40412794f856a91602477bf From f758fb826f58754d17dab137f0c40e5e039a1ff1 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Mon, 29 Apr 2024 22:23:27 +0530 Subject: [PATCH 087/108] INFRA-3188 | Dhruv | migration fix --- .../V1.76__Add_team_in_jit_approval_table.sql | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/resources/db/migration/V1.76__Add_team_in_jit_approval_table.sql b/src/main/resources/db/migration/V1.76__Add_team_in_jit_approval_table.sql index d981631a..406b6dbd 100644 --- a/src/main/resources/db/migration/V1.76__Add_team_in_jit_approval_table.sql +++ b/src/main/resources/db/migration/V1.76__Add_team_in_jit_approval_table.sql @@ -1 +1,10 @@ -ALTER TABLE jit_approvals ADD COLUMN team_id BIGINT NOT NULL REFERENCES team(id); \ No newline at end of file +ALTER TABLE jit_approvals ADD COLUMN team_id BIGINT references team(id); + +UPDATE jit_approvals ja +SET team_id = ( + SELECT team_id + FROM jit_requests jr + WHERE ja.jit_id = jr.id +); + +ALTER TABLE jit_approvals ALTER COLUMN team_id SET NOT NULL; From aea1a6be25c0caf4b0041dbd35c093975a62ea51 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Tue, 30 Apr 2024 13:01:37 +0530 Subject: [PATCH 088/108] INFRA-3188 | Dhruv | update slack message --- .../infra/portal/v2/jit/service/JitServiceImpl.java | 13 +++++++++---- .../infra/portal/v2/jit/utils/SlackBotUtil.java | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 9872eef8..e50f291b 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -139,8 +139,11 @@ class JitServiceImpl implements JitService { jitRequest.setRequestorSlackMessageTimestamp(messageTimestamp); } - private void updateRequestorNoReviewersDmOnSlack(JitRequest jitRequest) throws IOException { - SlackBotAttachment personalMessage = slackBotUtil.getRequestorNoReviewerDm(jitRequest); + private void updateRequestorNoReviewersDmOnSlack( + JitRequest jitRequest, + List missingTeams + ) throws IOException { + SlackBotAttachment personalMessage = slackBotUtil.getRequestorNoReviewerDm(missingTeams); slackBotClient.postMessage( userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); } @@ -418,7 +421,8 @@ class JitServiceImpl implements JitService { if (reviewers.size() == 0) { // no reviewers found, inform user - updateRequestorNoReviewersDmOnSlack(jitRequest); + updateRequestorNoReviewersDmOnSlack(jitRequest, + List.of(jitRequest.getTeam().getName())); throw new IllegalStateException("No reviewers found"); } @@ -439,7 +443,8 @@ class JitServiceImpl implements JitService { if (!teamsWithoutReviewers.isEmpty()) { // no reviwers found for additional teams, inform user - updateRequestorNoReviewersDmOnSlack(jitRequest); + updateRequestorNoReviewersDmOnSlack(jitRequest, teamsWithoutReviewers.stream() + .map(Team::getName).collect(Collectors.toList())); throw new IllegalStateException( "No reviewers found for additional teams : " + teamsWithoutReviewers.stream() .map(Team::getName).collect(Collectors.joining(","))); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index 006a59a2..1357f6c1 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -132,13 +132,13 @@ public class SlackBotUtil { } public SlackBotAttachment getRequestorNoReviewerDm( - JitRequest jitRequest + List missingTeams ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format( "No Reviewers present for team(s): %s. Kindly get notify team to have reviewers. " + "Contact Cloud Platform oncall if issue persists", - jitRequest.getTeam().getName())); + String.join(", ", missingTeams))); SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( SlackMessageBlockType.SECTION, reviewRequestText, null, null); From 0a5e97c5e0c8394d8f291d4ef470335afb60de78 Mon Sep 17 00:00:00 2001 From: Saurabh Bhagwan Sathe Date: Tue, 30 Apr 2024 14:02:32 +0530 Subject: [PATCH 089/108] INFRA-3090 | Saurabh | Json schema for dynamo-db alerts (#911) Co-authored-by: Ashvin S --- .../jsonschema/extraResources/dynamodb.json | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/resources/jsonschema/extraResources/dynamodb.json b/src/main/resources/jsonschema/extraResources/dynamodb.json index b52520a2..ab0ab646 100644 --- a/src/main/resources/jsonschema/extraResources/dynamodb.json +++ b/src/main/resources/jsonschema/extraResources/dynamodb.json @@ -8,7 +8,9 @@ "required": [ "tableName", "billingMode", - "hashKey" + "hashKey", + "dynamoDbAlertDurations", + "dynamoDbAlertThresholds" ], "properties": { "tableName": { @@ -58,6 +60,40 @@ "maxWriteCapacity": { "type": "number" }, + "dynamoDbAlertDurations": { + "type": "object", + "required": [ + "systemError", + "throttledRequest" + ], + "properties": { + "systemError": { + "type": "number", + "minimum": 0 + }, + "throttledRequest": { + "type": "number", + "minimum": 0 + } + } + }, + "dynamoDbAlertThresholds": { + "type": "object", + "required": [ + "systemError", + "throttledRequest" + ], + "properties": { + "systemError": { + "type": "number", + "minimum": 0 + }, + "throttledRequest": { + "type": "number", + "minimum": 0 + } + } + }, "ttl": { "type": "object", "required": [ From fee9fea21131aee0a553eefa6f19a4c6dce309de Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Tue, 30 Apr 2024 15:05:58 +0530 Subject: [PATCH 090/108] INFRA-3188 | Dhruv | use team instead of user for slack message --- .../repository/JitApprovalsRepository.java | 6 +- .../portal/v2/jit/service/JitServiceImpl.java | 75 +++++++++---------- .../infra/portal/v2/jit/utils/AuthUtil.java | 17 +++-- .../portal/v2/jit/utils/SlackBotUtil.java | 40 +++++----- .../portal/v2/jit/utils/AuthUtilTest.java | 16 ++-- 5 files changed, 78 insertions(+), 76 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java index 37a1f71a..6ceb8b41 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/repository/JitApprovalsRepository.java @@ -27,8 +27,8 @@ public interface JitApprovalsRepository extends JpaRepository + "GROUP BY ja.team_id", nativeQuery = true) List countApprovedInEachTeam(Long jitId); - - @Query(value = "SELECT ja.reviewer_id FROM jit_approvals ja " + + @Query(value = "SELECT DISTINCT ja.team_id FROM jit_approvals ja " + "WHERE ja.jit_id = :jitId and ja.action = :action", nativeQuery = true) - List findReviewersByAction(Long jitId, String action); + List findReviewerTeamsByAction(Long jitId, String action); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index e50f291b..c4e27f21 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -123,16 +123,16 @@ class JitServiceImpl implements JitService { private void updateRequestorDmOnSlack( JitRequest jitRequest, - List pendingReviewers, - List approvedReviewers, - List rejectedReviewers, + List pendingTeams, + List approvedTeams, + List rejectedTeams, boolean actionEnabled, SlackColor color ) throws IOException { SlackBotAttachment personalMessage = slackBotUtil.getRequestorDm( - jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingReviewers, - approvedReviewers, rejectedReviewers, jitRequest.getStatus().toString(), color); + jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingTeams, + approvedTeams, rejectedTeams, jitRequest.getStatus().toString(), color); String messageTimestamp = slackBotClient.postMessage( userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); @@ -157,15 +157,15 @@ class JitServiceImpl implements JitService { private void updateChannelOnSlack( JitRequest jitRequest, - List pendingReviewers, - List approvedReviewers, - List rejectedReviewers, + List pendingTeams, + List approvedTeams, + List rejectedTeams, SlackColor color ) throws IOException { SlackBotAttachment commonChannelMessage = slackBotUtil.getChannelMessage(jitRequest, - jitRequest.getRequestedFor().getEmail(), pendingReviewers, approvedReviewers, - rejectedReviewers, color); + jitRequest.getRequestedFor().getEmail(), pendingTeams, approvedTeams, + rejectedTeams, color); String messageTimestamp = slackBotClient.postMessage(commonChannelId, commonChannelMessage); jitRequest.setChannelSlackMessageTimestamp(messageTimestamp); } @@ -241,27 +241,27 @@ class JitServiceImpl implements JitService { jitApprovalsRepository.save(jitApproval); // reviewer lists(pending, approved, rejected) and count of approvals depends on above - List pendingReviewers = authUtil.getReviewersByAction(userService, + List pendingTeams = authUtil.getReviewerTeamsByAction( jitRequest.getId(), JitRequestStatus.PENDING); - List approvedReviewers = authUtil.getReviewersByAction(userService, + List approvedTeams = authUtil.getReviewerTeamsByAction( jitRequest.getId(), JitRequestStatus.APPROVED); - List rejectedReviewers = authUtil.getReviewersByAction(userService, + List rejectedTeams = authUtil.getReviewerTeamsByAction( jitRequest.getId(), JitRequestStatus.REJECTED); - flowFunction.apply(reviewerEmail, jitApproval, jitRequest, pendingReviewers, - approvedReviewers, rejectedReviewers); + flowFunction.apply(reviewerEmail, jitApproval, jitRequest, pendingTeams, + approvedTeams, rejectedTeams); } private void jitApprovedFlow( String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest, - List pendingReviewers, - List approvedReviewers, - List rejectedReviewers + List pendingTeams, + List approvedTeams, + List rejectedTeams ) throws IOException { try { @@ -290,10 +290,10 @@ class JitServiceImpl implements JitService { SlackColor.APPROVED); // send group message to common channel with details on pending and approved reviewers - updateChannelOnSlack(jitRequest, pendingReviewers, approvedReviewers, - rejectedReviewers, SlackColor.APPROVED); - updateRequestorDmOnSlack(jitRequest, pendingReviewers, - approvedReviewers, rejectedReviewers, actionEnabled, SlackColor.APPROVED); + updateChannelOnSlack(jitRequest, pendingTeams, approvedTeams, + rejectedTeams, SlackColor.APPROVED); + updateRequestorDmOnSlack(jitRequest, pendingTeams, + approvedTeams, rejectedTeams, actionEnabled, SlackColor.APPROVED); jitRequestRepository.save(jitRequest); jitApprovalsRepository.save(jitApproval); @@ -307,9 +307,9 @@ class JitServiceImpl implements JitService { String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest, - List pendingReviewers, - List approvedReviewers, - List rejectedReviewers + List pendingTeams, + List approvedTeams, + List rejectedTeams ) throws ConnectException { try { jitApproval.setAction(JitRequestStatus.REJECTED); @@ -317,10 +317,10 @@ class JitServiceImpl implements JitService { updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false, SlackColor.REJECTED); - updateRequestorDmOnSlack(jitRequest, pendingReviewers, - approvedReviewers, rejectedReviewers, false, SlackColor.REJECTED); - updateChannelOnSlack(jitRequest, pendingReviewers, approvedReviewers, - rejectedReviewers, SlackColor.REJECTED); + updateRequestorDmOnSlack(jitRequest, pendingTeams, + approvedTeams, rejectedTeams, false, SlackColor.REJECTED); + updateChannelOnSlack(jitRequest, pendingTeams, approvedTeams, + rejectedTeams, SlackColor.REJECTED); jitApprovalsRepository.save(jitApproval); jitRequestRepository.save(jitRequest); @@ -451,7 +451,7 @@ class JitServiceImpl implements JitService { } List jitApprovals = new ArrayList<>(); - List pendingReviewers = new ArrayList<>(); + List pendingTeams = new ArrayList<>(); for (User reviewer : reviewers) { JitApproval jitApproval = new JitApproval(jitRequest, reviewer, @@ -460,23 +460,22 @@ class JitServiceImpl implements JitService { jitApprovals.add(jitApproval); // send review request/message to reviewers - String reviewersEmail = reviewer.getEmail(); - pendingReviewers.add(reviewersEmail); + pendingTeams.add(jitRequest.getTeam().getName()); } additionalTeamReviewers.forEach((team, users) -> users.forEach(reviewer -> { JitApproval jitApproval = new JitApproval(jitRequest, reviewer, team, JitRequestStatus.PENDING); jitApprovals.add(jitApproval); - pendingReviewers.add(reviewer.getEmail()); + pendingTeams.add(team.getName()); })); // send personal message to user with details on pending and approved reviewers JitRequest jitRequestWithId = jitRequestRepository.save(jitRequest); - updateRequestorDmOnSlack(jitRequestWithId, pendingReviewers, + updateRequestorDmOnSlack(jitRequestWithId, pendingTeams, new ArrayList<>(), new ArrayList<>(), true, SlackColor.INFO); // send group message to common channel with details on pending and approved reviewers - updateChannelOnSlack(jitRequest, pendingReviewers, new ArrayList<>(), + updateChannelOnSlack(jitRequest, pendingTeams, new ArrayList<>(), new ArrayList<>(), SlackColor.INFO); List jitApprovalsWithId = jitApprovalsRepository.saveAll(jitApprovals); @@ -528,9 +527,9 @@ class JitServiceImpl implements JitService { String reviewerEmail, JitApproval jitApproval, JitRequest jitRequest, - List pendingReviewers, - List approvedReviewers, - List rejectedReviewers + List pendingTeams, + List approvedTeams, + List rejectedTeams ) throws IOException; } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 028d1c85..6da168fd 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -3,6 +3,7 @@ package com.navi.infra.portal.v2.jit.utils; import static com.navi.infra.portal.v2.role.Actor.JITREVIEWER; import com.navi.infra.portal.domain.user.Role; +import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; import com.navi.infra.portal.v2.jit.entity.Environment; @@ -10,7 +11,7 @@ import com.navi.infra.portal.v2.jit.entity.JitApproval; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; -import com.navi.infra.portal.v2.role.RoleService; +import com.navi.infra.portal.v2.team.TeamService; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -25,7 +26,7 @@ import org.springframework.stereotype.Component; public class AuthUtil { private final UserService userService; - private final RoleService roleService; + private final TeamService teamService; private final JitApprovalsRepository jitApprovalsRepository; @Value("${jit.number_of_prod_approvals}") @@ -66,13 +67,15 @@ public class AuthUtil { || hasPortalApprovalAccess(userRoles); } - public List getReviewersByAction( - UserService userService, Long jitId, JitRequestStatus jitRequestStatus + public List getReviewerTeamsByAction( + Long jitId, JitRequestStatus jitRequestStatus ) { - return userService.findAllByIds( - jitApprovalsRepository.findReviewersByAction(jitId, jitRequestStatus.toString())) + return teamService.findAllByIds( + jitApprovalsRepository + .findReviewerTeamsByAction(jitId, jitRequestStatus.toString())) .parallelStream() - .map(User::getEmail) + .map(Team::getName) + .sorted() .collect(Collectors.toList()); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index 1357f6c1..6cd7ba38 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -89,24 +89,22 @@ public class SlackBotUtil { String userEmail, JitRequest jitRequest, Boolean actionEnabled, - List pendingReviewers, - List approvedReviewers, - List rejectedReviewers, + List pendingTeams, + List approvedTeams, + List rejectedTeams, String requestStatus, SlackColor color ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format("Access request *#%s* raised for user %s\n" - + "\tPending Reviewers: %s\n" - + "\tApproved Reviewers: %s\n" - + "\tRejected Reviewers: %s\n" - + "\tApprovals required: %s\n" + + "\tReviews required from: %s\n" + + "\tApproved by: %s\n" + + "\tRejected by: %s\n" + "\tCurrent Status: %s\n", jitRequest.getId().toString(), userEmail, - String.join(", ", pendingReviewers), - String.join(", ", approvedReviewers), - String.join(", ", rejectedReviewers), - jitRequest.getEnvironment().approvals, + String.join(", ", pendingTeams), + String.join(", ", approvedTeams), + String.join(", ", rejectedTeams), requestStatus)); SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( @@ -170,23 +168,21 @@ public class SlackBotUtil { public SlackBotAttachment getChannelMessage( JitRequest jitRequest, String email, - List pendingReviewers, - List approvedReviewers, - List rejectedReviewers, + List pendingTeams, + List approvedTeams, + List rejectedTeams, SlackColor color ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format("Access request *#%s* raised for user %s\n" - + "\tPending Reviewers: %s\n" - + "\tApproved By: %s\n" - + "\tRejected By: %s\n" - + "\tApprovals required: %s\n" + + "\tReviews required from: %s\n" + + "\tApproved by: %s\n" + + "\tRejected by: %s\n" + "\tCurrent status: %s", jitRequest.getId().toString(), email, - String.join(", ", pendingReviewers), - String.join(", ", approvedReviewers), - String.join(", ", rejectedReviewers), - jitRequest.getEnvironment().approvals, + String.join(", ", pendingTeams), + String.join(", ", approvedTeams), + String.join(", ", rejectedTeams), jitRequest.getStatus().toString())); SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java index d4a70a3a..45ac195c 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -15,6 +15,7 @@ import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; import com.navi.infra.portal.v2.role.RoleService; +import com.navi.infra.portal.v2.team.TeamService; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -28,11 +29,12 @@ public class AuthUtilTest { // Generate test cases for isAuthorized method private final UserService userService = mock(UserService.class); + private final TeamService teamService = mock(TeamService.class); private final RoleService roleService = mock(RoleService.class); private final JitApprovalsRepository jitApprovalsRepository = mock( JitApprovalsRepository.class); - AuthUtil authUtil = new AuthUtil(userService, roleService, jitApprovalsRepository); + AuthUtil authUtil = new AuthUtil(userService, teamService, roleService, jitApprovalsRepository); private User getTestUser() { User testUser = new User(); @@ -66,14 +68,16 @@ public class AuthUtilTest { public void testGetReviewersByAction() { // Generate test cases for getReviewersByAction method User testUser = getTestUser(); + Team userTeam = new Team("Infra"); + testUser.setTeams(Collections.singletonList(userTeam)); - when(jitApprovalsRepository.findReviewersByAction(1L, "APPROVED")).thenReturn( + when(jitApprovalsRepository.findReviewerTeamsByAction(1L, "APPROVED")).thenReturn( Collections.singletonList(1L)); - when(userService.findAllByIds(Collections.singletonList(1L))).thenReturn( - Collections.singletonList(testUser)); + when(teamService.findAllByIds(Collections.singletonList(1L))).thenReturn( + Collections.singletonList(userTeam)); - Assert.assertEquals(List.of("harinder.singh@navi.com"), - authUtil.getReviewersByAction(userService, 1L, JitRequestStatus.APPROVED)); + Assert.assertEquals(List.of("Infra"), + authUtil.getReviewerTeamsByAction(1L, JitRequestStatus.APPROVED)); } @Test From 859f149bc2843c0c4d6f1639c7ec3641723dae2a Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Tue, 30 Apr 2024 15:16:42 +0530 Subject: [PATCH 091/108] INFRA-3188 | Dhruv | code cleanup --- .../java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java index 45ac195c..479311d3 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/AuthUtilTest.java @@ -14,7 +14,6 @@ import com.navi.infra.portal.v2.jit.entity.JitApproval; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; import com.navi.infra.portal.v2.jit.repository.JitApprovalsRepository; -import com.navi.infra.portal.v2.role.RoleService; import com.navi.infra.portal.v2.team.TeamService; import java.util.ArrayList; import java.util.Collections; @@ -30,11 +29,10 @@ public class AuthUtilTest { // Generate test cases for isAuthorized method private final UserService userService = mock(UserService.class); private final TeamService teamService = mock(TeamService.class); - private final RoleService roleService = mock(RoleService.class); private final JitApprovalsRepository jitApprovalsRepository = mock( JitApprovalsRepository.class); - AuthUtil authUtil = new AuthUtil(userService, teamService, roleService, jitApprovalsRepository); + AuthUtil authUtil = new AuthUtil(userService, teamService, jitApprovalsRepository); private User getTestUser() { User testUser = new User(); From 99f008fed3c2ca952597525bc4a8c2722e21da76 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Tue, 30 Apr 2024 15:50:56 +0530 Subject: [PATCH 092/108] INFRA-3188 | Dhruv | fix-multiple team --- .../portal/v2/jit/service/JitServiceImpl.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index c4e27f21..69c4d8bc 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -458,16 +458,18 @@ class JitServiceImpl implements JitService { jitRequest.getTeam(), JitRequestStatus.PENDING); jitApprovals.add(jitApproval); - - // send review request/message to reviewers - pendingTeams.add(jitRequest.getTeam().getName()); } - additionalTeamReviewers.forEach((team, users) -> users.forEach(reviewer -> { - JitApproval jitApproval = new JitApproval(jitRequest, reviewer, team, - JitRequestStatus.PENDING); - jitApprovals.add(jitApproval); + pendingTeams.add(jitRequest.getTeam().getName()); + + additionalTeamReviewers.forEach((team, users) -> { + users.forEach(reviewer -> { + JitApproval jitApproval = new JitApproval(jitRequest, reviewer, team, + JitRequestStatus.PENDING); + jitApprovals.add(jitApproval); + }); pendingTeams.add(team.getName()); - })); + }); + pendingTeams.sort(String::compareTo); // send personal message to user with details on pending and approved reviewers JitRequest jitRequestWithId = jitRequestRepository.save(jitRequest); From 2c05633e631892c5c58dfd1bae0af066f08f0fdd Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Tue, 30 Apr 2024 16:10:04 +0530 Subject: [PATCH 093/108] INFRA-3188 | Dhruv | multiple user for same team --- src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index 6da168fd..cfc93f75 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -108,6 +108,7 @@ public class AuthUtil { return Stream.concat(environmentSpecificReviewers.stream(), allEnvironmentReviewers.stream()) + .distinct() .collect(Collectors.toList()); // TODO Add exception in case no reviewers found // TODO reduce number of userService calls thereby reducing DB calls From b09040b9d33e508e50a239c8d6e1941f920aa678 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Tue, 30 Apr 2024 16:35:29 +0530 Subject: [PATCH 094/108] INFRA-3219 | Harinder | Update resource action, review as a member of and ID for easier review and issue debugging --- .../com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java | 6 +++++- .../navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index 6cd7ba38..466fc6ef 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -25,10 +25,14 @@ public class SlackBotUtil { JitApproval jitApproval ) { return new ArrayList<>(Arrays.asList( - createField("Request ID", jitRequest.getId().toString()), + createField("ID", + String.join("-", jitRequest.getId().toString(), + jitApproval.getId().toString())), createField("User", userEmail), createField("Environment", jitRequest.getEnvironment().toString()), createField("Resource", jitRequest.getResourceType()), + createField("Action", jitRequest.getResourceAction()), + createField("Review as", jitApproval.getTeam().getName()), createField("Grant At/On", jitRequest.getGrantAt().truncatedTo(ChronoUnit.MINUTES).toString()), createField("Status", jitApproval.getAction().toString()) diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java index a8c1e279..b06418bf 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java @@ -28,6 +28,7 @@ public class SlackBotUtilTest { jitApproval.setAction(JitRequestStatus.PENDING); jitApproval.setId(1L); jitRequest.setId(1L); + jitApproval.setTeam(new Team("Infra")); SlackBotAttachment result = slackBotUtil.getReviewerDm(userEmail, jitRequest, jitApproval, true, SlackColor.INFO); From 7d9b5bac0c2408a4e746110b890af8a4c16d5d69 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Tue, 30 Apr 2024 19:16:56 +0530 Subject: [PATCH 095/108] INFRA-3188 | Dhruv | remove approve count and use atleast 1 team approval --- .../portal/v2/jit/entity/Environment.java | 22 +++++++++---------- .../infra/portal/v2/jit/utils/AuthUtil.java | 12 +++------- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java index 178d89b8..55bc9dc3 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/Environment.java @@ -1,21 +1,19 @@ package com.navi.infra.portal.v2.jit.entity; public enum Environment { - DEV("dev", 1), - QA("qa", 1), - PROD("prod", 2), - NONPROD("nonprod", 1), - CMD("cmd", 2), - PERF("perf", 1), - UAT("uat", 1), - DATA_PLATFORM_NONPROD("data-platform-nonprod", 1), - DATA_PLATFORM_PROD("data-platform-prod", 2); + DEV("dev"), + QA("qa"), + PROD("prod"), + NONPROD("nonprod"), + CMD("cmd"), + PERF("perf"), + UAT("uat"), + DATA_PLATFORM_NONPROD("data-platform-nonprod"), + DATA_PLATFORM_PROD("data-platform-prod"); public final String type; - public final Long approvals; - Environment(String type, int approvals) { + Environment(String type) { this.type = type; - this.approvals = (long) approvals; } } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java index cfc93f75..e81b0ab9 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/AuthUtil.java @@ -6,7 +6,6 @@ import com.navi.infra.portal.domain.user.Role; import com.navi.infra.portal.domain.user.Team; import com.navi.infra.portal.domain.user.User; import com.navi.infra.portal.service.user.UserService; -import com.navi.infra.portal.v2.jit.entity.Environment; import com.navi.infra.portal.v2.jit.entity.JitApproval; import com.navi.infra.portal.v2.jit.entity.JitRequest; import com.navi.infra.portal.v2.jit.entity.JitRequestStatus; @@ -79,20 +78,15 @@ public class AuthUtil { .collect(Collectors.toList()); } - Long findTotalApprovalsIfAllTeamsApproved(Long jitId) { + boolean hasApprovalsFromAllRequiredTeams(Long jitId) { List approvalList = jitApprovalsRepository.countApprovedInEachTeam(jitId); - long totalApproved = approvalList.stream().reduce(0L, Long::sum); - boolean allTeamApproval = approvalList.stream() - .allMatch(approval -> approval >= 1); - return allTeamApproval ? totalApproved : 0; + return approvalList.stream().allMatch(approval -> approval >= 1); } public boolean haveRequiredApprovals(JitRequest jitRequest) { - Environment env = jitRequest.getEnvironment(); - Long approvedRequests = findTotalApprovalsIfAllTeamsApproved(jitRequest.getId()); + return hasApprovalsFromAllRequiredTeams(jitRequest.getId()); // is atleast one approval from each required team obtained based on the mapping in yaml // and required approval type (master or something) - return approvedRequests >= env.approvals; } public List getReviewersFromRole(String teamName, String reviewerRoleType) { From c263337618153e93632ea2afe047d9a8f5385ede Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 1 May 2024 00:41:05 +0530 Subject: [PATCH 096/108] INFRA-3209 | Dhruv | add github action for kutegen commit check --- .github/workflows/kutegen_submodule_check.yml | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/kutegen_submodule_check.yml diff --git a/.github/workflows/kutegen_submodule_check.yml b/.github/workflows/kutegen_submodule_check.yml new file mode 100644 index 00000000..223d64a0 --- /dev/null +++ b/.github/workflows/kutegen_submodule_check.yml @@ -0,0 +1,41 @@ +name: Kutegen submodule check + +on: + pull_request: + branches: + - master + - main +permissions: + contents: read + pull-requests: read + +jobs: + submodule-check: + runs-on: "docker" + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + token: ${{ secrets.github_token }} + fetch-depth: 0 + fetch-tags: true + - name: Submodule update + run: git submodule update --init --recursive --depth 0 + - name: Check submodule + run: | + cd kutegen + git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" + git fetch origin main + BEHIND=$(git rev-list main ^HEAD --count) + AHEAD=$(git rev-list HEAD ^main --count) + if [ $AHEAD -gt 2 ]; then + echo "Submodule is more than 2 commits ahead of main branch." + exit 1 + elif [ $BEHIND -gt 2 ]; then + echo "Submodule is more than 2 commits behind main branch." + exit 1 + else + echo "Submodule is within 2 commits of main branch." + fi From ab8065d621376d75a9dd28182a5b6269a98f5527 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 1 May 2024 01:46:33 +0530 Subject: [PATCH 097/108] INFRA-3228 | Dhruv | Remove ids key from securityGroup while export --- .../com/navi/infra/portal/service/manifest/ManifestService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java index 80764314..b918c088 100644 --- a/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java +++ b/src/main/java/com/navi/infra/portal/service/manifest/ManifestService.java @@ -753,7 +753,7 @@ public class ManifestService { public Map exportManifestById(Long id) { final Set keysToExclude = Set.of("version", "id", "infraVertical", "cluster"); - final Map keysToReplace = Map.of("isDeployed", false); + final Map keysToReplace = Map.of("isDeployed", false, "ids", emptyList()); var manifest = fetchById(id); var manifestAsMap = manifest.convertToMap(); ObjectTransformationUtil.removeKeys(manifestAsMap, keysToExclude); From 31ea99011907226b9aa4472b3384cf5478937958 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Wed, 1 May 2024 14:08:52 +0530 Subject: [PATCH 098/108] INFRA-3209 | Dhruv | change token key --- .github/workflows/kutegen_submodule_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/kutegen_submodule_check.yml b/.github/workflows/kutegen_submodule_check.yml index 223d64a0..c96c1465 100644 --- a/.github/workflows/kutegen_submodule_check.yml +++ b/.github/workflows/kutegen_submodule_check.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 with: submodules: recursive - token: ${{ secrets.github_token }} + token: ${{ secrets.GIT_HUB_TOKEN }} fetch-depth: 0 fetch-tags: true - name: Submodule update From e3096d8f4eab9771c4a2f9902af19786c455660e Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Thu, 2 May 2024 11:18:10 +0530 Subject: [PATCH 099/108] INFRA-3209 | Dhruv | change token key --- .github/workflows/kutegen_submodule_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/kutegen_submodule_check.yml b/.github/workflows/kutegen_submodule_check.yml index c96c1465..055a460e 100644 --- a/.github/workflows/kutegen_submodule_check.yml +++ b/.github/workflows/kutegen_submodule_check.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 with: submodules: recursive - token: ${{ secrets.GIT_HUB_TOKEN }} + token: ${{ secrets.GIT_HUB_ACCESS_TOKEN }} fetch-depth: 0 fetch-tags: true - name: Submodule update From d102387d4739c74ae61bc8b8f530b8e8d12dc3de Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Thu, 2 May 2024 11:24:36 +0530 Subject: [PATCH 100/108] INFRA-3209 | Dhruv | test more than 2 commit difference --- .github/workflows/kutegen_submodule_check.yml | 4 ++-- kutegen | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/kutegen_submodule_check.yml b/.github/workflows/kutegen_submodule_check.yml index 055a460e..7441e63b 100644 --- a/.github/workflows/kutegen_submodule_check.yml +++ b/.github/workflows/kutegen_submodule_check.yml @@ -28,8 +28,8 @@ jobs: cd kutegen git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" git fetch origin main - BEHIND=$(git rev-list main ^HEAD --count) - AHEAD=$(git rev-list HEAD ^main --count) + BEHIND=$(git rev-list origin/main ^HEAD --count) + AHEAD=$(git rev-list HEAD ^origin/main --count) if [ $AHEAD -gt 2 ]; then echo "Submodule is more than 2 commits ahead of main branch." exit 1 diff --git a/kutegen b/kutegen index c5f45680..90000767 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit c5f456804ceea1d8c40412794f856a91602477bf +Subproject commit 90000767627e98565a5d0f94de25bc5dd36dd95d From be69740cbc540dbb7c6705ca7e5b1d15f7e20b86 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Thu, 2 May 2024 11:28:40 +0530 Subject: [PATCH 101/108] INFRA-3209 | Dhruv | update kutegen --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 90000767..c5f45680 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 90000767627e98565a5d0f94de25bc5dd36dd95d +Subproject commit c5f456804ceea1d8c40412794f856a91602477bf From 6db48280fdf5aa98388f6e001977c2b3d6d4e0b2 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Thu, 2 May 2024 12:14:49 +0530 Subject: [PATCH 102/108] INFRA-3209 | Dhruv | update check failure condition --- .github/workflows/kutegen_submodule_check.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/kutegen_submodule_check.yml b/.github/workflows/kutegen_submodule_check.yml index 7441e63b..7adb3018 100644 --- a/.github/workflows/kutegen_submodule_check.yml +++ b/.github/workflows/kutegen_submodule_check.yml @@ -30,12 +30,8 @@ jobs: git fetch origin main BEHIND=$(git rev-list origin/main ^HEAD --count) AHEAD=$(git rev-list HEAD ^origin/main --count) - if [ $AHEAD -gt 2 ]; then - echo "Submodule is more than 2 commits ahead of main branch." + if [ $AHEAD -ne 0] || [$BEHIND -ne 0 ]; then + echo "Submodule is not up to date with main branch." exit 1 - elif [ $BEHIND -gt 2 ]; then - echo "Submodule is more than 2 commits behind main branch." - exit 1 - else - echo "Submodule is within 2 commits of main branch." fi + echo "Submodule is up to date with main branch." \ No newline at end of file From 23506c53d79c885f4f25e63918a29aa02c9dd89b Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Thu, 2 May 2024 12:19:49 +0530 Subject: [PATCH 103/108] INFRA-3209 | Dhruv | update check failure condition --- .github/workflows/kutegen_submodule_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/kutegen_submodule_check.yml b/.github/workflows/kutegen_submodule_check.yml index 7adb3018..1ada04f8 100644 --- a/.github/workflows/kutegen_submodule_check.yml +++ b/.github/workflows/kutegen_submodule_check.yml @@ -30,7 +30,7 @@ jobs: git fetch origin main BEHIND=$(git rev-list origin/main ^HEAD --count) AHEAD=$(git rev-list HEAD ^origin/main --count) - if [ $AHEAD -ne 0] || [$BEHIND -ne 0 ]; then + if [ $AHEAD -ne 0 ] || [ $BEHIND -ne 0 ]; then echo "Submodule is not up to date with main branch." exit 1 fi From a81d9950ca18389a0e48569c5ccb632842eac43a Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Thu, 2 May 2024 12:27:31 +0530 Subject: [PATCH 104/108] INFRA-3209 | Dhruv | test old kutegen version --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index c5f45680..1c865e64 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit c5f456804ceea1d8c40412794f856a91602477bf +Subproject commit 1c865e6497e30dd9167787bbc5dafe4e89d78c5b From 1a06e19709575547cf5414642cea5a9be47bd4b9 Mon Sep 17 00:00:00 2001 From: dhruvjoshi Date: Thu, 2 May 2024 12:28:50 +0530 Subject: [PATCH 105/108] INFRA-3209 | Dhruv | update kutegen --- kutegen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kutegen b/kutegen index 1c865e64..c5f45680 160000 --- a/kutegen +++ b/kutegen @@ -1 +1 @@ -Subproject commit 1c865e6497e30dd9167787bbc5dafe4e89d78c5b +Subproject commit c5f456804ceea1d8c40412794f856a91602477bf From 980dc5a8909d8d907fd04709bcd3017e5506e169 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 2 May 2024 16:39:25 +0530 Subject: [PATCH 106/108] INFRA-3219 | Harinder | JIT enhancements - update message in place. Provide better information on reviews(pending from, approved by, rejected by) --- .../portal/v2/jit/entity/JitApproval.java | 2 + .../portal/v2/jit/entity/JitRequest.java | 2 + .../portal/v2/jit/service/JitServiceImpl.java | 79 ++++++++++++++++--- .../portal/v2/jit/utils/SlackBotUtil.java | 4 +- .../v2/slackbotclient/SlackBotClient.java | 20 +++-- ...1.77__Add_bot_channel_id_in_jit_tables.sql | 2 + .../v2/jit/service/JitServiceImplTest.java | 5 +- 7 files changed, 91 insertions(+), 23 deletions(-) create mode 100644 src/main/resources/db/migration/V1.77__Add_bot_channel_id_in_jit_tables.sql diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java index 1b4ed8a8..e0de85f7 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitApproval.java @@ -56,6 +56,8 @@ public class JitApproval extends BaseEntity { private String reviewerSlackMessageTimestamp; + private String botChannelId; + public JitApproval(JitRequest jitRequest, User reviewer, Team team, JitRequestStatus action) { this.jitRequest = jitRequest; this.reviewer = reviewer; diff --git a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java index 016df0e6..16ac48af 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/entity/JitRequest.java @@ -68,6 +68,8 @@ public class JitRequest extends BaseEntity { private String channelSlackMessageTimestamp; + private String botChannelId; + public JitRequest( User requestedFor, User requestedBy, diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 69c4d8bc..9dabcf2b 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -61,6 +61,7 @@ class JitServiceImpl implements JitService { @Value("${jit.slack.common.channel.id}") private final String commonChannelId; + public JitServiceImpl( JitRequestsRepository jitRequestRepository, JitApprovalsRepository jitApprovalsRepository, @@ -104,6 +105,24 @@ class JitServiceImpl implements JitService { return !existingDuplicates.isEmpty(); } + private void postReviewerDmOnSlack( + User reviewer, + JitRequest jitRequest, + JitApproval jitApproval, + boolean actionEnabled, + SlackColor color + ) + throws IOException { + SlackBotAttachment reviewMessage = slackBotUtil.getReviewerDm( + jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled, color); + var result = slackBotClient.postMessage(userService.getUsersSlackId(reviewer), + reviewMessage); + + jitApproval.setReviewerSlackMessageTimestamp(result.getTs()); + jitApproval.setBotChannelId(result.getChannel()); + jitApprovalsRepository.save(jitApproval); + } + private void updateReviewerDmOnSlack( User reviewer, JitRequest jitRequest, @@ -114,11 +133,29 @@ class JitServiceImpl implements JitService { throws IOException { SlackBotAttachment reviewMessage = slackBotUtil.getReviewerDm( jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled, color); - String messageTimestamp = slackBotClient.postMessage( - userService.getUsersSlackId(reviewer), reviewMessage); - jitApproval.setReviewerSlackMessageTimestamp(messageTimestamp); - jitApprovalsRepository.save(jitApproval); + slackBotClient.updateMessage(jitApproval.getBotChannelId(), reviewMessage, + jitApproval.getReviewerSlackMessageTimestamp()); + } + + private void postRequestorDmOnSlack( + JitRequest jitRequest, + List pendingTeams, + List approvedTeams, + List rejectedTeams, + boolean actionEnabled, + SlackColor color + ) + throws IOException { + SlackBotAttachment personalMessage = slackBotUtil.getRequestorDm( + jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingTeams, + approvedTeams, rejectedTeams, jitRequest.getStatus().toString(), color); + + var result = slackBotClient.postMessage( + userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); + + jitRequest.setRequestorSlackMessageTimestamp(result.getTs()); + jitRequest.setBotChannelId(result.getChannel()); } private void updateRequestorDmOnSlack( @@ -134,9 +171,8 @@ class JitServiceImpl implements JitService { jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingTeams, approvedTeams, rejectedTeams, jitRequest.getStatus().toString(), color); - String messageTimestamp = slackBotClient.postMessage( - userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); - jitRequest.setRequestorSlackMessageTimestamp(messageTimestamp); + slackBotClient.updateMessage(jitRequest.getBotChannelId(), personalMessage, + jitRequest.getRequestorSlackMessageTimestamp()); } private void updateRequestorNoReviewersDmOnSlack( @@ -155,6 +191,22 @@ class JitServiceImpl implements JitService { userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); } + private void postChannelOnSlack( + JitRequest jitRequest, + List pendingTeams, + List approvedTeams, + List rejectedTeams, + SlackColor color + ) + throws IOException { + SlackBotAttachment commonChannelMessage = slackBotUtil.getChannelMessage(jitRequest, + jitRequest.getRequestedFor().getEmail(), pendingTeams, approvedTeams, + rejectedTeams, color); + + var result = slackBotClient.postMessage(commonChannelId, commonChannelMessage); + jitRequest.setChannelSlackMessageTimestamp(result.getTs()); + } + private void updateChannelOnSlack( JitRequest jitRequest, List pendingTeams, @@ -166,8 +218,8 @@ class JitServiceImpl implements JitService { SlackBotAttachment commonChannelMessage = slackBotUtil.getChannelMessage(jitRequest, jitRequest.getRequestedFor().getEmail(), pendingTeams, approvedTeams, rejectedTeams, color); - String messageTimestamp = slackBotClient.postMessage(commonChannelId, commonChannelMessage); - jitRequest.setChannelSlackMessageTimestamp(messageTimestamp); + slackBotClient.updateMessage(commonChannelId, commonChannelMessage, + jitRequest.getChannelSlackMessageTimestamp()); } private void validateGrantTime(JitRequest jitRequest) { @@ -251,6 +303,9 @@ class JitServiceImpl implements JitService { jitRequest.getId(), JitRequestStatus.REJECTED); + pendingTeams.removeAll(approvedTeams); + pendingTeams.removeAll(rejectedTeams); + flowFunction.apply(reviewerEmail, jitApproval, jitRequest, pendingTeams, approvedTeams, rejectedTeams); } @@ -473,18 +528,18 @@ class JitServiceImpl implements JitService { // send personal message to user with details on pending and approved reviewers JitRequest jitRequestWithId = jitRequestRepository.save(jitRequest); - updateRequestorDmOnSlack(jitRequestWithId, pendingTeams, + postRequestorDmOnSlack(jitRequestWithId, pendingTeams, new ArrayList<>(), new ArrayList<>(), true, SlackColor.INFO); // send group message to common channel with details on pending and approved reviewers - updateChannelOnSlack(jitRequest, pendingTeams, new ArrayList<>(), + postChannelOnSlack(jitRequest, pendingTeams, new ArrayList<>(), new ArrayList<>(), SlackColor.INFO); List jitApprovalsWithId = jitApprovalsRepository.saveAll(jitApprovals); JitRequest finalJitRequest = jitRequest; jitApprovalsWithId.stream().forEach(jitApproval -> { try { - updateReviewerDmOnSlack(jitApproval.getReviewer(), + postReviewerDmOnSlack(jitApproval.getReviewer(), finalJitRequest, jitApproval, true, SlackColor.INFO); } catch (IOException e) { throw new RuntimeException(e); diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index 466fc6ef..7bc48848 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -101,7 +101,7 @@ public class SlackBotUtil { ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format("Access request *#%s* raised for user %s\n" - + "\tReviews required from: %s\n" + + "\tReviews pending from: %s\n" + "\tApproved by: %s\n" + "\tRejected by: %s\n" + "\tCurrent Status: %s\n", @@ -179,7 +179,7 @@ public class SlackBotUtil { ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, String.format("Access request *#%s* raised for user %s\n" - + "\tReviews required from: %s\n" + + "\tReviews pending from: %s\n" + "\tApproved by: %s\n" + "\tRejected by: %s\n" + "\tCurrent status: %s", diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java index e967ec07..fb591dcf 100644 --- a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java @@ -4,8 +4,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.slack.api.Slack; import com.slack.api.methods.MethodsClient; import com.slack.api.methods.SlackApiException; +import com.slack.api.methods.response.chat.ChatPostMessageResponse; import com.slack.api.model.User; import java.io.IOException; +import java.net.ConnectException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -54,26 +56,29 @@ public class SlackBotClient { return userSlackIdMap; } - public String postMessage(String channelId, SlackBotAttachment slackBotAttachment) + public ChatPostMessageResponse postMessage(String channelId, SlackBotAttachment slackBotAttachment) throws IOException { // Slack client reference: https://api.slack.com/methods/chat.postMessage/code + ChatPostMessageResponse result = new ChatPostMessageResponse(); try { ObjectMapper objectMapper = new ObjectMapper(); String textJson = "[" + objectMapper.writeValueAsString(slackBotAttachment) + "]"; - var result = client.chatPostMessage(r -> r + result = client.chatPostMessage(r -> r .token(slackBotToken) .channel(channelId) .text("Just In Time Access Manager") .attachmentsAsString(textJson) ); - return result.getTs(); + if(!result.isOk()){ + log.error("Unable to process Slack API request: {}", result.getError()); + } } catch (IOException | SlackApiException e) { log.error("error: {}", e.getMessage(), e); } - return ""; + return result; } - public String updateMessage(String channelId, SlackBotAttachment slackBotAttachment, String ts) + public void updateMessage(String channelId, SlackBotAttachment slackBotAttachment, String ts) throws IOException { try { ObjectMapper objectMapper = new ObjectMapper(); @@ -85,10 +90,11 @@ public class SlackBotClient { .text("Just In Time Access Manager") .attachmentsAsString(textJson) ); - return result.getTs(); + if(!result.isOk()){ + log.error("Unable to process Slack API request: {}", result.getError()); + } } catch (IOException | SlackApiException e) { log.error("error: {}", e.getMessage(), e); } - return ""; } } diff --git a/src/main/resources/db/migration/V1.77__Add_bot_channel_id_in_jit_tables.sql b/src/main/resources/db/migration/V1.77__Add_bot_channel_id_in_jit_tables.sql new file mode 100644 index 00000000..5f87e088 --- /dev/null +++ b/src/main/resources/db/migration/V1.77__Add_bot_channel_id_in_jit_tables.sql @@ -0,0 +1,2 @@ +ALTER TABLE jit_requests ADD COLUMN bot_channel_id character varying(255); +ALTER TABLE jit_approvals ADD COLUMN bot_channel_id character varying(255); diff --git a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java index ed6fd76d..f80dabe0 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/service/JitServiceImplTest.java @@ -27,6 +27,7 @@ import com.navi.infra.portal.v2.jit.utils.SlackBotUtil; import com.navi.infra.portal.v2.role.RoleService; import com.navi.infra.portal.v2.slackbotclient.SlackBotClient; import com.navi.infra.portal.v2.team.TeamService; +import com.slack.api.methods.response.chat.ChatPostMessageResponse; import java.io.IOException; import java.time.LocalDateTime; import java.util.List; @@ -142,7 +143,7 @@ class JitServiceImplTest { when(jitRequestRepository.save(any())).thenReturn(jitRequestWithId); when(userService.getUsersSlackId(jitRequest.getRequestedFor())).thenReturn("U12314"); - when(slackBotClient.postMessage(any(), any())).thenReturn("2341419824719"); + when(slackBotClient.postMessage(any(), any())).thenReturn(new ChatPostMessageResponse()); when(jitApprovalsRepository.saveAll(any())).thenReturn(jitApprovalsWithId); jitServiceImpl.createJitRequest(jitRequestDto); @@ -165,7 +166,7 @@ class JitServiceImplTest { when(authUtil.getReviewers(jitRequestWithId.getTeam().getName(), jitRequestWithId.getEnvironment().type)).thenReturn(reviewers); when(userService.getUsersSlackId(jitRequest.getRequestedFor())).thenReturn("U12314"); - when(slackBotClient.postMessage(any(), any())).thenReturn("2341419824719"); + when(slackBotClient.postMessage(any(), any())).thenReturn(new ChatPostMessageResponse()); assertThrows(IllegalStateException.class, () -> { jitServiceImpl.createJitRequest(jitRequestDto); }); From fc9a7e95e9dc9521757583a29aa151afa89559cd Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 2 May 2024 17:02:01 +0530 Subject: [PATCH 107/108] INFRA-3219 | Harinder | Addressing comments from reviewdog --- .../portal/v2/slackbotclient/SlackBotClient.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java index fb591dcf..0a830d4f 100644 --- a/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java +++ b/src/main/java/com/navi/infra/portal/v2/slackbotclient/SlackBotClient.java @@ -1,13 +1,11 @@ package com.navi.infra.portal.v2.slackbotclient; import com.fasterxml.jackson.databind.ObjectMapper; -import com.slack.api.Slack; import com.slack.api.methods.MethodsClient; import com.slack.api.methods.SlackApiException; import com.slack.api.methods.response.chat.ChatPostMessageResponse; import com.slack.api.model.User; import java.io.IOException; -import java.net.ConnectException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -56,7 +54,10 @@ public class SlackBotClient { return userSlackIdMap; } - public ChatPostMessageResponse postMessage(String channelId, SlackBotAttachment slackBotAttachment) + public ChatPostMessageResponse postMessage( + String channelId, + SlackBotAttachment slackBotAttachment + ) throws IOException { // Slack client reference: https://api.slack.com/methods/chat.postMessage/code ChatPostMessageResponse result = new ChatPostMessageResponse(); @@ -69,7 +70,7 @@ public class SlackBotClient { .text("Just In Time Access Manager") .attachmentsAsString(textJson) ); - if(!result.isOk()){ + if (!result.isOk()) { log.error("Unable to process Slack API request: {}", result.getError()); } } catch (IOException | SlackApiException e) { @@ -90,7 +91,7 @@ public class SlackBotClient { .text("Just In Time Access Manager") .attachmentsAsString(textJson) ); - if(!result.isOk()){ + if (!result.isOk()) { log.error("Unable to process Slack API request: {}", result.getError()); } } catch (IOException | SlackApiException e) { From 4c7761a656033e032756d6e4552e37189ca10f39 Mon Sep 17 00:00:00 2001 From: Harinder Singh Date: Thu, 2 May 2024 18:17:38 +0530 Subject: [PATCH 108/108] INFRA-3219 | Harinder | Restructuring code --- .../portal/v2/jit/service/JitServiceImpl.java | 131 +++++++----------- .../portal/v2/jit/utils/SlackBotUtil.java | 11 +- .../portal/v2/jit/utils/SlackBotUtilTest.java | 12 +- 3 files changed, 62 insertions(+), 92 deletions(-) diff --git a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java index 9dabcf2b..8a6865db 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/service/JitServiceImpl.java @@ -107,14 +107,9 @@ class JitServiceImpl implements JitService { private void postReviewerDmOnSlack( User reviewer, - JitRequest jitRequest, JitApproval jitApproval, - boolean actionEnabled, - SlackColor color - ) - throws IOException { - SlackBotAttachment reviewMessage = slackBotUtil.getReviewerDm( - jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled, color); + SlackBotAttachment reviewMessage + ) throws IOException { var result = slackBotClient.postMessage(userService.getUsersSlackId(reviewer), reviewMessage); @@ -124,33 +119,17 @@ class JitServiceImpl implements JitService { } private void updateReviewerDmOnSlack( - User reviewer, - JitRequest jitRequest, JitApproval jitApproval, - boolean actionEnabled, - SlackColor color - ) - throws IOException { - SlackBotAttachment reviewMessage = slackBotUtil.getReviewerDm( - jitRequest.getRequestedFor().getEmail(), jitRequest, jitApproval, actionEnabled, color); - + SlackBotAttachment reviewMessage + ) throws IOException { slackBotClient.updateMessage(jitApproval.getBotChannelId(), reviewMessage, jitApproval.getReviewerSlackMessageTimestamp()); } private void postRequestorDmOnSlack( JitRequest jitRequest, - List pendingTeams, - List approvedTeams, - List rejectedTeams, - boolean actionEnabled, - SlackColor color - ) - throws IOException { - SlackBotAttachment personalMessage = slackBotUtil.getRequestorDm( - jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingTeams, - approvedTeams, rejectedTeams, jitRequest.getStatus().toString(), color); - + SlackBotAttachment personalMessage + ) throws IOException { var result = slackBotClient.postMessage( userService.getUsersSlackId(jitRequest.getRequestedFor()), personalMessage); @@ -160,18 +139,9 @@ class JitServiceImpl implements JitService { private void updateRequestorDmOnSlack( JitRequest jitRequest, - List pendingTeams, - List approvedTeams, - List rejectedTeams, - boolean actionEnabled, - SlackColor color - ) - throws IOException { - SlackBotAttachment personalMessage = slackBotUtil.getRequestorDm( - jitRequest.getRequestedFor().getEmail(), jitRequest, actionEnabled, pendingTeams, - approvedTeams, rejectedTeams, jitRequest.getStatus().toString(), color); - - slackBotClient.updateMessage(jitRequest.getBotChannelId(), personalMessage, + SlackBotAttachment requestorMessage + ) throws IOException { + slackBotClient.updateMessage(jitRequest.getBotChannelId(), requestorMessage, jitRequest.getRequestorSlackMessageTimestamp()); } @@ -193,31 +163,16 @@ class JitServiceImpl implements JitService { private void postChannelOnSlack( JitRequest jitRequest, - List pendingTeams, - List approvedTeams, - List rejectedTeams, - SlackColor color - ) - throws IOException { - SlackBotAttachment commonChannelMessage = slackBotUtil.getChannelMessage(jitRequest, - jitRequest.getRequestedFor().getEmail(), pendingTeams, approvedTeams, - rejectedTeams, color); - + SlackBotAttachment commonChannelMessage + ) throws IOException { var result = slackBotClient.postMessage(commonChannelId, commonChannelMessage); jitRequest.setChannelSlackMessageTimestamp(result.getTs()); } private void updateChannelOnSlack( JitRequest jitRequest, - List pendingTeams, - List approvedTeams, - List rejectedTeams, - SlackColor color - ) - throws IOException { - SlackBotAttachment commonChannelMessage = slackBotUtil.getChannelMessage(jitRequest, - jitRequest.getRequestedFor().getEmail(), pendingTeams, approvedTeams, - rejectedTeams, color); + SlackBotAttachment commonChannelMessage + ) throws IOException { slackBotClient.updateMessage(commonChannelId, commonChannelMessage, jitRequest.getChannelSlackMessageTimestamp()); } @@ -341,14 +296,17 @@ class JitServiceImpl implements JitService { actionEnabled = false; } // inform reviewer on slack that request is approved and remove action buttons - updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false, - SlackColor.APPROVED); + updateReviewerDmOnSlack(jitApproval, + slackBotUtil.getReviewerDm(jitRequest.getRequestedFor().getEmail(), jitRequest, + jitApproval, false, SlackColor.APPROVED)); // send group message to common channel with details on pending and approved reviewers - updateChannelOnSlack(jitRequest, pendingTeams, approvedTeams, - rejectedTeams, SlackColor.APPROVED); - updateRequestorDmOnSlack(jitRequest, pendingTeams, - approvedTeams, rejectedTeams, actionEnabled, SlackColor.APPROVED); + updateChannelOnSlack(jitRequest, + slackBotUtil.getChannelMessage(jitRequest, pendingTeams, approvedTeams, + rejectedTeams, SlackColor.APPROVED)); + updateRequestorDmOnSlack(jitRequest, + slackBotUtil.getRequestorDm(jitRequest, actionEnabled, pendingTeams, approvedTeams, + rejectedTeams, SlackColor.APPROVED)); jitRequestRepository.save(jitRequest); jitApprovalsRepository.save(jitApproval); @@ -370,12 +328,15 @@ class JitServiceImpl implements JitService { jitApproval.setAction(JitRequestStatus.REJECTED); jitRequest.setStatus(JitRequestStatus.REJECTED); - updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, false, - SlackColor.REJECTED); - updateRequestorDmOnSlack(jitRequest, pendingTeams, - approvedTeams, rejectedTeams, false, SlackColor.REJECTED); - updateChannelOnSlack(jitRequest, pendingTeams, approvedTeams, - rejectedTeams, SlackColor.REJECTED); + updateReviewerDmOnSlack(jitApproval, + slackBotUtil.getReviewerDm(jitRequest.getRequestedFor().getEmail(), jitRequest, + jitApproval, false, SlackColor.REJECTED)); + updateRequestorDmOnSlack(jitRequest, + slackBotUtil.getRequestorDm(jitRequest, false, pendingTeams, + approvedTeams, rejectedTeams, SlackColor.REJECTED)); + updateChannelOnSlack(jitRequest, + slackBotUtil.getChannelMessage(jitRequest, pendingTeams, approvedTeams, + rejectedTeams, SlackColor.REJECTED)); jitApprovalsRepository.save(jitApproval); jitRequestRepository.save(jitRequest); @@ -395,13 +356,16 @@ class JitServiceImpl implements JitService { jitApproval.setReviewedAt(LocalDateTime.now()); jitApproval.setAction(JitRequestStatus.CANCELLED); jitApprovalsRepository.save(jitApproval); - updateReviewerDmOnSlack(jitApproval.getReviewer(), jitRequest, jitApproval, - false, SlackColor.REJECTED); + updateReviewerDmOnSlack(jitApproval, + slackBotUtil.getReviewerDm(jitRequest.getRequestedFor().getEmail(), jitRequest, + jitApproval, false, SlackColor.REJECTED)); } - updateChannelOnSlack(jitRequest, new ArrayList<>(), new ArrayList<>(), - new ArrayList<>(), SlackColor.REJECTED); - updateRequestorDmOnSlack(jitRequest, new ArrayList<>(), - new ArrayList<>(), new ArrayList<>(), false, SlackColor.REJECTED); + updateChannelOnSlack(jitRequest, + slackBotUtil.getChannelMessage(jitRequest, new ArrayList<>(), new ArrayList<>(), + new ArrayList<>(), SlackColor.REJECTED)); + updateRequestorDmOnSlack(jitRequest, + slackBotUtil.getRequestorDm(jitRequest, false, new ArrayList<>(), + new ArrayList<>(), new ArrayList<>(), SlackColor.REJECTED)); jitRequestRepository.save(jitRequest); } catch (Exception e) { log.error(ExceptionAirflowOrDb, e.getCause()); @@ -528,19 +492,22 @@ class JitServiceImpl implements JitService { // send personal message to user with details on pending and approved reviewers JitRequest jitRequestWithId = jitRequestRepository.save(jitRequest); - postRequestorDmOnSlack(jitRequestWithId, pendingTeams, - new ArrayList<>(), new ArrayList<>(), true, SlackColor.INFO); + postRequestorDmOnSlack(jitRequestWithId, + slackBotUtil.getRequestorDm(jitRequestWithId, true, pendingTeams, + new ArrayList<>(), new ArrayList<>(), SlackColor.INFO)); // send group message to common channel with details on pending and approved reviewers - postChannelOnSlack(jitRequest, pendingTeams, new ArrayList<>(), - new ArrayList<>(), SlackColor.INFO); + postChannelOnSlack(jitRequest, + slackBotUtil.getChannelMessage(jitRequest, pendingTeams, new ArrayList<>(), + new ArrayList<>(), SlackColor.INFO)); List jitApprovalsWithId = jitApprovalsRepository.saveAll(jitApprovals); JitRequest finalJitRequest = jitRequest; jitApprovalsWithId.stream().forEach(jitApproval -> { try { - postReviewerDmOnSlack(jitApproval.getReviewer(), - finalJitRequest, jitApproval, true, SlackColor.INFO); + postReviewerDmOnSlack(jitApproval.getReviewer(), jitApproval, + slackBotUtil.getReviewerDm(finalJitRequest.getRequestedFor().getEmail(), + finalJitRequest, jitApproval, true, SlackColor.INFO)); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java index 7bc48848..c87f4a39 100644 --- a/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java +++ b/src/main/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtil.java @@ -27,7 +27,7 @@ public class SlackBotUtil { return new ArrayList<>(Arrays.asList( createField("ID", String.join("-", jitRequest.getId().toString(), - jitApproval.getId().toString())), + jitApproval.getId().toString())), createField("User", userEmail), createField("Environment", jitRequest.getEnvironment().toString()), createField("Resource", jitRequest.getResourceType()), @@ -90,13 +90,11 @@ public class SlackBotUtil { } public SlackBotAttachment getRequestorDm( - String userEmail, JitRequest jitRequest, Boolean actionEnabled, List pendingTeams, List approvedTeams, List rejectedTeams, - String requestStatus, SlackColor color ) { SlackMessageText reviewRequestText = new SlackMessageText(SlackMessageTextType.MARKDOWN, @@ -105,11 +103,11 @@ public class SlackBotUtil { + "\tApproved by: %s\n" + "\tRejected by: %s\n" + "\tCurrent Status: %s\n", - jitRequest.getId().toString(), userEmail, + jitRequest.getId().toString(), jitRequest.getRequestedFor().getEmail(), String.join(", ", pendingTeams), String.join(", ", approvedTeams), String.join(", ", rejectedTeams), - requestStatus)); + jitRequest.getStatus().toString())); SlackBotMessageBlock reviewRequestSection = new SlackBotMessageBlock( SlackMessageBlockType.SECTION, reviewRequestText, null, null); @@ -171,7 +169,6 @@ public class SlackBotUtil { public SlackBotAttachment getChannelMessage( JitRequest jitRequest, - String email, List pendingTeams, List approvedTeams, List rejectedTeams, @@ -183,7 +180,7 @@ public class SlackBotUtil { + "\tApproved by: %s\n" + "\tRejected by: %s\n" + "\tCurrent status: %s", - jitRequest.getId().toString(), email, + jitRequest.getId().toString(), jitRequest.getRequestedFor().getEmail(), String.join(", ", pendingTeams), String.join(", ", approvedTeams), String.join(", ", rejectedTeams), diff --git a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java index b06418bf..79d098cc 100644 --- a/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java +++ b/src/test/java/com/navi/infra/portal/v2/jit/utils/SlackBotUtilTest.java @@ -22,6 +22,7 @@ public class SlackBotUtilTest { new Team("Infra"), Environment.DEV, "RDS", "dev-db", "read", JitRequestStatus.PENDING, 5L, LocalDateTime.now()); JitApproval jitApproval = new JitApproval(); + User testUser = new User(); @Test public void testGetReviewerMessage_ActionEnabled() { @@ -39,9 +40,12 @@ public class SlackBotUtilTest { @Test public void testPersonalMessage_ActionEnabled() { jitRequest.setId(2L); + testUser.setEmail(userEmail); + jitRequest.setRequestedFor(testUser); + SlackBotAttachment result = - slackBotUtil.getRequestorDm(userEmail, jitRequest, true, - new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), "PENDING", + slackBotUtil.getRequestorDm(jitRequest, true, + new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), SlackColor.INFO); Assertions.assertEquals(2, result.getBlocks().size()); // Section + action block @@ -50,8 +54,10 @@ public class SlackBotUtilTest { @Test public void testGroupMessage() { jitRequest.setId(1L); + testUser.setEmail(userEmail); + jitRequest.setRequestedFor(testUser); SlackBotAttachment result = - slackBotUtil.getChannelMessage(jitRequest, userEmail, new ArrayList<>(), + slackBotUtil.getChannelMessage(jitRequest, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), SlackColor.INFO); Assertions.assertEquals(1, result.getBlocks().size()); // Section