Skip to content

Commit

Permalink
Merge pull request #9 from NTF-marketplace/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
min-96 authored Aug 6, 2024
2 parents 60b4bb9 + f191296 commit 62e0bd6
Show file tree
Hide file tree
Showing 25 changed files with 714 additions and 26 deletions.
199 changes: 199 additions & 0 deletions .github/workflows/cicd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
name: Create and publish a container image, update helm chart 'appVersion'

on:
push:
branches: ["main", "develop"]

#############################################
#
# Branch
# - develop > GitHub packages
# - main > Amazon ECR
#
#############################################

jobs:
develop:
### Reference
# https://docs.github.com/ko/actions/publishing-packages/publishing-docker-images#github-packages%EC%97%90-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EA%B2%8C%EC%8B%9C
###

if: github.ref == 'refs/heads/develop'
name: Build and Push Container Image to GitHub Container Registry
runs-on: ubuntu-latest
env:
REPOSITORY: auth
ENVIRONMENT: dev
permissions:
contents: read
packages: write
attestations: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to the GitHub container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Container image
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ghcr.io/${{ github.repository }}
tags: type=sha

- name: Set up JDK 21
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '21'

- name: Build JAR
run: ./gradlew clean build -x test

- name: Build and push Docker image
id: push
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

# ### Error
# # [message] Failed to persist attestation
# # Feature not available for the NTF-marketplace organization.
# # To enable this feature, please upgrade the billing plan, or make this repository public.
# # https://docs.github.com/rest/repos/repos#create-an-attestation
# ###
# - name: Generate artifact attestation
# uses: actions/attest-build-provenance@v1
# with:
# subject-name: ${{ env.REGISTRY }}/${{ github.repository }}
# subject-digest: ${{ steps.push.outputs.digest }}
# push-to-registry: true

- name: Checkout Private Repository
uses: actions/checkout@v4
with:
repository: NTF-marketplace/devops
fetch-depth: 0
ref: develop
token: ${{ secrets.PAT }}

- name: Replace image tag in helm values.yaml
uses: mikefarah/yq@master
env:
IMAGE_VERSION: ${{ steps.meta.outputs.version }}
with:
cmd: yq eval -i '.image.tag = env(IMAGE_VERSION)' 'chart/${{ env.REPOSITORY }}_${{ env.ENVIRONMENT }}/values.yaml'

- name: Commit helm chart changes
env:
IMAGE_VERSION: ${{ steps.meta.outputs.version }}
run: |
cd chart/${{ env.REPOSITORY }}_${{ env.ENVIRONMENT }}
git config --global user.email "[email protected]"
git config --global user.name "dongdorrong"
git add values.yaml
git commit --message "ci: update ${{ env.REPOSITORY }}_${{ env.ENVIRONMENT }} image tag to $IMAGE_VERSION"
- name: Push commit
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.PAT }}
repository: NTF-marketplace/devops
branch: develop

main:
if: github.ref == 'refs/heads/main'
name: Build and Push Container Image to Amazon ECR
runs-on: ubuntu-latest
env:
REPOSITORY: auth
ENVIRONMENT: prod
permissions:
contents: read
packages: write
attestations: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_DEFAULT_REGION }}

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2

- name: Extract metadata (tags, labels) for Container image
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ secrets.AWS_DEFAULT_REGION }}.amazonaws.com/${{ env.REPOSITORY }}_${{ env.ENVIRONMENT }}
tags: type=sha

- name: Set up JDK 21
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '21'

- name: Build JAR
run: ./gradlew clean build -x test

- name: Build and push Docker image
id: push
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Checkout Private Repository
uses: actions/checkout@v4
with:
repository: NTF-marketplace/devops
fetch-depth: 0
ref: develop
token: ${{ secrets.PAT }}

- name: Replace image tag in helm values.yaml
uses: mikefarah/yq@master
env:
IMAGE_VERSION: ${{ steps.meta.outputs.version }}
with:
cmd: yq eval -i '.image.tag = env(IMAGE_VERSION)' 'chart/${{ env.REPOSITORY }}_${{ env.ENVIRONMENT }}/values.yaml'

- name: Commit helm chart changes
env:
IMAGE_VERSION: ${{ steps.meta.outputs.version }}
run: |
cd chart/${{ env.REPOSITORY }}_${{ env.ENVIRONMENT }}
git config --global user.email "[email protected]"
git config --global user.name "dongdorrong"
git add values.yaml
git commit --message "ci: update ${{ env.REPOSITORY }}_${{ env.ENVIRONMENT }} image tag to $IMAGE_VERSION"
- name: Push commit
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.PAT }}
repository: NTF-marketplace/devops
branch: develop
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ out/

### Kotlin ###
.kotlin

### DevOps ###
build/
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM amazoncorretto:21-alpine

COPY build/libs/*.jar /app.jar

RUN apk update && apk upgrade && \
# apk add --no-cache <necessary-packages> && \
rm -rf /var/cache/apk/*

ENTRYPOINT ["java", "-jar", "app.jar"]
27 changes: 25 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,22 @@ group = "com.api"
version = "0.0.1-SNAPSHOT"

java {
sourceCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_21
}

repositories {
mavenCentral()
}

extra["springCloudVersion"] = "2023.0.2"

dependencies {
implementation("org.springframework.cloud:spring-cloud-starter-config")
implementation("org.springframework.boot:spring-boot-starter-oauth2-authorization-server")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.security:spring-security-config")


implementation("org.postgresql:r2dbc-postgresql:1.0.4.RELEASE")
Expand All @@ -42,15 +46,34 @@ dependencies {
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
testImplementation("org.springframework.security:spring-security-test")

// [DevOps] Prometheus - Metrics
implementation("io.micrometer:micrometer-core")
implementation("io.micrometer:micrometer-registry-prometheus")

// [DevOps] OpenTelemetry - Tracing
implementation("io.micrometer:micrometer-tracing-bridge-otel")
implementation("io.opentelemetry:opentelemetry-exporter-zipkin")
}

dependencyManagement {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
}
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
jvmTarget = "17"
jvmTarget = "21"
}
}

tasks.withType<Test> {
useJUnitPlatform()
}

// DevOps
tasks.jar {
enabled = false
}
1 change: 1 addition & 0 deletions rsaKey.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"p":"wm3zSzOs0ijBC86Xx9vv8bpRVWUg5ePcgiPdE1GlMoJSZYJhH6i7EUwp_DiFhD6mRNW6qOKayps1gMI2Nli-nrg-pfR5DvVm-mm_LcDXcsgyjluIzQnBhheQCaDrH-EsBbwsPOKSJu6y5m0Jl0x8Ujm2ZdHgROJhUfzBo7UpC6k","kty":"RSA","q":"3R8mTnOr1qx5xr6UG6xRTjhi23YQ8rxkF6UAU8RodaOY4qVgji_7N7QZ74oTcOlvqjVrzsvCOAOGtP9y-zdC0EZJ8liAHq2zFJz-OE58o1aHM51ctYJJczRnN2DxPHNd6FBS0CSbKel3Jp_hAwFdPgq1rE0lr8lKZ1VbZKqXXP0","d":"Isb3iUumXJbTDZxz9JrNhPN0YCrjTp7sh3lMndajPmCGK-GzFedSmLxaJ6Ycoh3WywyjbW75SCASgGb5N0ny2ojp2F9GuIANJrRyw4QCFyW1O1q8NcKszZOCpT1TvwBj4hnOdfT-UX9AcWojfDcp8ud66IWZJALUHk4WeczIaFUymGyS5CGfg00JLnsZujWyeDiuqlhVj0Ln5KPMfRpfQwQNhuDu5bc-HME6LLppXF6XecYoZFRw4_CrlyBxwZvdAhMNPnai-kqXo3KSjvPls1T6g0Yw6hXYBYItmU12BmRKLiANRlFCjkLjsHP7XGJapIR1hB5BgecKCojI35dY0Q","e":"AQAB","kid":"19bd04f8-c4dd-40df-a784-bcf95596e696","qi":"bJ_0jsbP50UntpFCQRS2-sCDj9bGU5TdZLNgPHaiyEjSCXP_3gI32FGWtD5A3l0PsXyMs-E9a71XkhOnNJXoyclPl3qtdnRByCAsM9-rdSco4gBgrj3D9AyQ2g4QRdSHhFds0UPOMha3cKfVoFuw6LqbKHCppNVJ3JwWkKo19MA","dp":"Y0r9bdFVF_rCI8J81w9mKX_qW38K3vyQN1ITa_NNN09AvyBnc2CbMElCQ9GlthS8mvi_m9ImFQRQvZHxV63Yo3waWmxQiqge0BHDFZ2fKbo9v1_VrEioMU_FOnWYvi4jakZgHTPkScerS2wx8reX4fIhSTx2mRc3dkRrq6wv6wk","dq":"0WB1fUO6KwQWK0K6K5n3QwHRWc1qLu6EOH9c1_TalMncMoA19W0pi41WIaO01O21do4vDxmRRkjQfQKFdarV8TEdRATZDDOdpp8heV-YVXHRg-Y1qwk7U4MDWUTKKFt1SE0GnWCMLBuNX110Ssw35k9tx0EltlX7xezlJWUC_mE","n":"p_CTcEkupLc6oAsyTKeoPpF6YsWeTIgjNLp7XfPHPcgU1RzGZOf8wbQrHvf_eeR-9xOUVL2MrFIalkWncWEoKL1kbEHj8khB_0tlIjQvyHaeOXmhVe2x0T6QQoxg7LI8IDZWEVMpuZN6zTjhMaGrP-NJcX_IC3fZUHuuUiJ3exb7-4I4fnOUblxq0HrrZQIBXkrNAVEjYdCh7MY475Hw314jy6NX0wly-xDFvaXG2mNJyov7cHhw93pD6zeFyX43BFgyxULFeVSz3xC8W91PAYKW-oqcyAXYVxbhP6NwKXYk1cAqDkn-o7u9JyrnRbR_hh1bGpOjd9YDifHc5HBCBQ"}
2 changes: 2 additions & 0 deletions src/main/kotlin/com/api/auth/AuthApplication.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.api.auth

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.ConfigurationPropertiesScan
import org.springframework.boot.runApplication

@SpringBootApplication
@ConfigurationPropertiesScan
class AuthApplication

fun main(args: Array<String>) {
Expand Down
38 changes: 38 additions & 0 deletions src/main/kotlin/com/api/auth/config/SecurityConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.api.auth.config

import com.api.auth.security.RefreshTokenValidationFilter
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.builders.WebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter


@Configuration
@EnableReactiveMethodSecurity
class SecurityConfig(
private val refreshTokenValidationFilter: RefreshTokenValidationFilter
) {
@Bean
fun webSecurityCustomizer(): WebSecurityCustomizer {
return WebSecurityCustomizer { web: WebSecurity -> web.ignoring().requestMatchers("/v1/auth") }
}

@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http
.csrf { it.disable() }
.authorizeHttpRequests {
it.requestMatchers("/v1/auth").permitAll()
it.requestMatchers("/v1/auth/reissue").authenticated()
it.anyRequest().authenticated()
}
.addFilterBefore(refreshTokenValidationFilter, UsernamePasswordAuthenticationFilter::class.java)


return http.build()
}
}
40 changes: 40 additions & 0 deletions src/main/kotlin/com/api/auth/controller/AuthController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.api.auth.controller

import com.api.auth.controller.dto.JwtRequest
import com.api.auth.controller.dto.JwtResponse
import com.api.auth.service.AuthService
import com.nimbusds.oauth2.sdk.TokenRequest
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.ReactiveSecurityContextHolder
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import reactor.core.publisher.Mono

@RestController
@RequestMapping("/v1/auth")
class AuthController(
private val authService: AuthService,
) {

@PostMapping
fun createToken(@RequestBody request: JwtRequest): Mono<ResponseEntity<JwtResponse>> {
return authService.createToken(request)
.flatMap {
Mono.just(ResponseEntity.ok().body(it))
}
.onErrorResume {
Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null))
}

}

@PostMapping("/reissue")
fun reissueAccessToken(authentication: Authentication): String {
return authService.reissueAccessToken(authentication.principal.toString())
}
}
5 changes: 5 additions & 0 deletions src/main/kotlin/com/api/auth/controller/dto/JwtRequest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.api.auth.controller.dto

data class JwtRequest(
val address: String
)
6 changes: 6 additions & 0 deletions src/main/kotlin/com/api/auth/controller/dto/JwtResponse.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.api.auth.controller.dto

data class JwtResponse(
val accessToken: String,
val refreshToken: String?,
)
Loading

0 comments on commit 62e0bd6

Please sign in to comment.