This commit is contained in:
孙小云 2025-12-04 15:50:55 +08:00
parent 9bab576c5c
commit 13db8a2600
11 changed files with 0 additions and 478 deletions

View File

@ -1,119 +0,0 @@
clone:
image: registry.t-aaron.com/drone/git:latest
kind: pipeline
type: kubernetes
name: gateway
volumes:
- name: maven-cache
host:
path: /opt/maven-cache-default
- name: sonar-cache
host:
path: /opt/sonar-cache-default
steps:
- name: download-dependencies
image: registry.t-aaron.com/maven:3.8.6-openjdk-11-slim
volumes:
- name: maven-cache
path: /root/.m2
commands:
- echo "配置 Maven 镜像源..."
- mkdir -p /root/.m2
- cp settings.xml /root/.m2/settings.xml
- echo "开始下载 Maven 依赖..."
- mvn dependency:go-offline -B
- echo "依赖下载完成!"
- echo "将本地 Maven 缓存同步到工作区用于后续构建..."
- mkdir -p /drone/src/.m2
- cp -a /root/.m2/. /drone/src/.m2/
- name: package
image: registry.t-aaron.com/maven:3.8.6-openjdk-11-slim
volumes:
- name: maven-cache
path: /root/.m2
commands:
- echo "配置 Maven 镜像源..."
- mkdir -p /root/.m2
- cp settings.xml /root/.m2/settings.xml
- echo "开始构建 JAR 包..."
- mvn clean package -DskipTests -B
- echo "JAR 包构建完成!"
- ls -la target/*.jar
when:
event: [ push, pull_request ]
depends_on:
- download-dependencies
- name: sonar-scan
image: registry.t-aaron.com/maven:3.8.6-openjdk-11-slim
volumes:
- name: maven-cache
path: /root/.m2
- name: sonar-cache
path: /root/.sonar/cache
commands:
- echo "配置 Maven 镜像源..."
- mkdir -p /root/.m2
- cp settings.xml /root/.m2/settings.xml
- echo "开始 SonarQube 代码质量检查..."
- echo "清理之前的构建文件..."
- rm -rf target/ .mvn/ .classpath .project .settings/
- echo "编译代码..."
- mvn clean compile
- echo "执行 SonarQube 扫描..."
- mvn sonar:sonar -Dsonar.projectKey=gateway -Dsonar.host.url=https://sonar-ops.t-aaron.com/sonar -Dsonar.login=$SONAR_TOKEN -Dsonar.projectName="Gateway" -Dsonar.projectVersion=${DRONE_COMMIT_SHA:0:8} -Dsonar.sources=src/main/java -Dsonar.java.binaries=target/classes
- echo "SonarQube 代码质量检查完成!"
environment:
SONAR_TOKEN:
from_secret: SONAR_TOKEN
when:
event: [ push, pull_request ]
depends_on:
- download-dependencies
- name: build-and-push
image: registry.t-aaron.com/plugins/kaniko
settings:
registry: registry.t-aaron.com
repo: registry.t-aaron.com/tuoheng/gateway
cache: true
cache_repo: registry.t-aaron.com/kaniko/cache-gateway
build_args:
- MAVEN_MIRROR_URL=https://maven.aliyun.com/repository/public
username:
from_secret: REGISTRY_USERNAME
password:
from_secret: REGISTRY_PASSWORD
tags:
- latest
- ${DRONE_COMMIT_SHA:0:8}
dockerfile: Dockerfile
context: .
when:
event: [ push, tag ]
depends_on:
- package
- name: deploy-to-k8s
image: registry.t-aaron.com/alpine/k8s:1.25.9
commands:
- echo "部署/更新 gateway 到 default 命名空间"
- |
kubectl create deployment gateway \
--image=registry.t-aaron.com/tuoheng/gateway:${DRONE_COMMIT_SHA:0:8} \
--port=8080 -n default --dry-run=client -o yaml | kubectl apply -f -
- kubectl set image deployment/gateway gateway=registry.t-aaron.com/tuoheng/gateway:${DRONE_COMMIT_SHA:0:8} -n default --record=true || true
- kubectl create service clusterip gateway --tcp=8080:8080 -n default --dry-run=client -o yaml | kubectl apply -f -
- echo "等待 Deployment 就绪..."
- kubectl rollout status deployment/gateway -n default --timeout=300s
- echo "查看服务与Pod状态"
- kubectl get deploy,svc -n default | grep -i gateway || true
- kubectl get pods -n default -l app=gateway || kubectl get pods -n default | grep gateway || true
when:
event: [ push ]
depends_on:
- build-and-push

1
gateway/.gitignore vendored
View File

@ -1 +0,0 @@
target/

View File

@ -1,27 +0,0 @@
# 生产阶段 - 仅复制预构建的 JAR 文件
FROM registry.t-aaron.com/openjdk:11-jre-slim
# 创建应用用户
RUN groupadd -r appuser && useradd -r -g appuser appuser
# 设置工作目录
WORKDIR /app
# 复制预构建的 JAR 文件
COPY target/*.jar app.jar
# 更改文件所有者
RUN chown -R appuser:appuser /app
# 切换到应用用户
USER appuser
# 暴露端口
EXPOSE 8080
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD netstat -an | grep :8080 | grep LISTEN || exit 1
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]

View File

@ -1,48 +0,0 @@
# Test pipeline trigger
# Test pipeline with secrets permission
# Test with image mirroring
# Test with local images - drone/git and drone/placeholder
# Test with updated RBAC permissions
# Test with uploaded alpine image
# Test host volume mount
# Test host volume mount again
# Test after server config update
# Test with emptyDir volume
Trigger new build
Trigger Kaniko build
Retrigger build with correct image
Trigger build test
Test build
Test registry mirror
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
xx
a
a
a
xx
xx
xx

View File

@ -1,122 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tuoheng</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>gateway</name>
<description>Spring Boot 2.7.x Servlet Gateway</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.8</spring-cloud.version>
</properties>
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- Spring Cloud Gateway (Servlet/MVC模式) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- OAuth2 Resource Server (JWT校验) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<!-- OAuth2 Client (TokenRelay等) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<!-- Nacos Discovery -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.0.5.0</version>
</dependency>
<!-- Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2021.0.5.0</version>
</dependency>
<!-- Spring Cloud Bootstrap -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.5</version>
</dependency>
<!-- Spring Cloud LoadBalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- JaCoCo 代码覆盖率插件 -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>compile</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- SonarQube 插件 -->
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.9.1.2184</version>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>aliyun-all</id>
<name>Aliyun Maven (all)</name>
<url>https://maven.aliyun.com/repository/public</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
</settings>

View File

@ -1,13 +0,0 @@
package com.tuoheng.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}

View File

@ -1,22 +0,0 @@
package com.tuoheng.gateway.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange(exchanges -> exchanges
.pathMatchers("/a/**").authenticated()
.pathMatchers("/b/**").authenticated()
.anyExchange().permitAll()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt());
return http.build();
}
}

View File

@ -1,77 +0,0 @@
package com.tuoheng.gateway.filter;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
@Component
public class JwtPermissionFilter implements GlobalFilter, Ordered {
/**
* 这边能获取到Token里面的值
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
// 获取完整的请求URL
String fullUrl = exchange.getRequest().getURI().toString();
System.out.println("用户访问的完整URL: " + fullUrl);
// 获取请求的path
String path = exchange.getRequest().getPath().toString();
System.out.println("用户访问的path: " + path);
// 获取请求的host
String host = exchange.getRequest().getHeaders().getHost().toString();
System.out.println("用户访问的host: " + host);
String hostName = exchange.getRequest().getHeaders().getHost().getHostName();
System.out.println("用户访问的域名: " + hostName);
// 获取Referer如果有
String referer = exchange.getRequest().getHeaders().getFirst("Referer");
System.out.println("Referer: " + referer);
// 从Spring Security上下文获取JWT
return ReactiveSecurityContextHolder.getContext()
.flatMap(securityContext -> {
if (securityContext.getAuthentication() instanceof JwtAuthenticationToken) {
JwtAuthenticationToken jwtAuth = (JwtAuthenticationToken) securityContext.getAuthentication();
Jwt jwt = jwtAuth.getToken();
String username = jwt.getClaimAsString("username");
String clientId = jwt.getClaimAsString("client_id");
String tenantCode = jwt.getClaimAsString("tenant_code");
String authorities = jwt.getClaimAsString("clientIds");
// 你可以在这里做权限判断
System.out.println("网关解析到token字段");
System.out.println("用户名: " + username);
System.out.println("客户端ID: " + clientId);
System.out.println("租户代码: " + tenantCode);
System.out.println("用户权限: " + authorities);
//该域名没有权限
if(!authorities.contains(hostName)){
exchange.getResponse().setStatusCode(org.springframework.http.HttpStatus.FORBIDDEN);
return exchange.getResponse().setComplete();
}
}
return chain.filter(exchange);
});
}
@Override
public int getOrder() {
return -1; // 优先级高
}
}

View File

@ -1,26 +0,0 @@
server.port=8080
# 应用名称
spring.application.name=gateway
# Nacos 服务发现配置
spring.cloud.nacos.discovery.server-addr=nacos:8848
spring.cloud.nacos.discovery.namespace=public
spring.cloud.nacos.discovery.group=DEFAULT_GROUP
spring.cloud.nacos.discovery.enabled=true
# Gateway 路由配置 - 使用服务发现
spring.cloud.gateway.routes[0].id=resource-server-a
spring.cloud.gateway.routes[0].uri=lb://aserver
spring.cloud.gateway.routes[0].predicates[0]=Path=/a/**
spring.cloud.gateway.routes[0].filters[0]=RewritePath=/a/(?<segment>.*), /api/${segment}
spring.cloud.gateway.routes[0].filters[1]=TokenRelay
spring.cloud.gateway.routes[1].id=resource-server-b
spring.cloud.gateway.routes[1].uri=lb://bserver
spring.cloud.gateway.routes[1].predicates[0]=Path=/b/**
spring.cloud.gateway.routes[1].filters[0]=RewritePath=/b/(?<segment>.*), /api/${segment}
spring.cloud.gateway.routes[1].filters[1]=TokenRelay
# OAuth2 配置
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://oidc:8080/oauth2/jwks

View File

@ -1,9 +0,0 @@
# Bootstrap configuration for Nacos config center
spring.application.name=gateway
# Nacos config center configuration
spring.cloud.nacos.config.server-addr=nacos:8848
spring.cloud.nacos.config.namespace=public
spring.cloud.nacos.config.group=DEFAULT_GROUP
spring.cloud.nacos.config.file-extension=properties
spring.cloud.nacos.config.enabled=true