在Google Cloud SQL环境中执行Maven单元测试

时间:2019-03-04 15:40:12

标签: maven unit-testing jenkins kubernetes google-cloud-sql

我在GCP的Kubernetes引擎中运行了一个Jenkins吊舱,我正在尝试运行一个连接到Google Cloud SQL数据库的Maven单元测试,以执行上述测试。我对项目的 application.yaml 如下:

package main

import (
    "fmt"
    "io"
    "os"
    "strings"

    "github.com/PuerkitoBio/goquery"
)

// recursive function
func dumpElement(i int, sel *goquery.Selection) {
    fmt.Println("dump Element - is this the first or last element? I don't know")
    sel.Contents().Each(dumpElement)
}

func startRecursion(r io.Reader) error {
    g, err := goquery.NewDocumentFromReader(r)
    if err != nil {
        return err
    }

    g.Find(":root > body").Each(dumpElement)
    return nil
}

func main() {
    doc := `<!DOCTYPE html>
    <html><head><title>foo</title></head><body>
    <div class="bla">foo <b> bar </b> baz</div>
    </body></html>`

    if err := startRecursion(strings.NewReader(doc)); err != nil {
        os.Exit(-1)
    }
}

与此项目关联的当前Jenkins文件是:

Jenkinsfile:

spring:
  cloud:
     gcp:
        project-id: <my_project_id>
     sql: 
        database-name: <my_database_name>
        instance-connection-name: <my_instance_connection_name>

  jpa:
     database-platform: org.hibernate.dialect.MySQL55Dialect
     hibernate:
        ddl-auto: create-drop

  datasource:
     continue-on-error: true
     driver-class-name: com.mysql.cj.jdbc.Driver
     username: <my_cloud_sql_username>
     password: <my_cloud_sql_password>

}

我的问题是当管道实际尝试使用以上配置(在我的application.yaml中)运行mvn测试时,出现此错误:

pipeline {
   agent any

   tools{
      maven 'Maven 3.5.2'
      jdk 'jdk8'
   }
   environment {
       IMAGE = readMavenPom().getArtifactId()
       VERSION = readMavenPom().getVersion()
       DEV_DB_USER = "${env.DEV_DB_USER}"
       DEV_DB_PASSWORD = "${env.DEV_DB_PASSWORD}"
    }

   stages {
      stage('Build docker image') {
        steps {
            sh 'mvn -Dmaven.test.skip=true clean package'
            script{
               docker.build '$IMAGE:$VERSION'
            }

        }
    }
       stage('Run unit tests') {

          steps {
            withEnv(['GCLOUD_PATH=/var/jenkins_home/google-cloud-sdk/bin']) {
                withCredentials([file(credentialsId: 'key-sa', variable: 'GC_KEY')]) {
                   sh("gcloud auth activate-service-account --key-file=${GC_KEY}")
                   sh("gcloud container clusters get-credentials <cluster_name> --zone northamerica-northeast1-a --project <project_id>")
                   sh 'mvn test'
                }
             }          
           }                
        }
    }
}

我有两个Google Cloud项目:

  • 具有运行Jenkins pod的Kubernetes集群的服务器。

  • K8s群集所在的另一个项目包含我实际的Spring Boot应用程序和我要访问的Cloud SQL数据库。

我还仅在我的Spring Boot项目中为Jenkins创建了服务帐户,以与三个角色一起使用:Cloud SQL编辑器,Kubernetes Engine群集管理员和项目所有者(以验证服务帐户没有问题)。

我在两个项目中都启用了Cloud SQL,Cloud SQL管理员和Kubernetes API,并且再次检查了Cloud SQL凭据,它们还可以。另外,我按照讨论的here的建议,使用创建服务帐户时生成的json文件对Jenkins管道进行了身份验证:

詹金斯文件(提取):

  Caused by: 
  com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 
  Forbidden
  {
     "code" : 403,
     "errors" : [ {
        "domain" : "global",
        "message" : "Insufficient Permission: Request had insufficient authentication scopes.",
        "reason" : "insufficientPermissions"
      } ],
     "message" : "Insufficient Permission: Request had insufficient authentication scopes."
  }

2 个答案:

答案 0 :(得分:0)

我完全不相信GCP Java SDK完全依赖于gcloud CLI。相反,它将查找指向您的服务帐户密钥文件和GCLOUD_PROJECT的环境变量GOOGLE_APPLICATION_CREDENTIALS(请参见https://cloud.google.com/docs/authentication/getting-started)。

尝试添加以下内容:

sh("export GOOGLE_APPLICATION_CREDENTIALS=${GC_KEY}")
sh("export GCLOUD_PROJECT=<project_id>")

答案 1 :(得分:0)

要验证此功能,您需要验证几件事。我假设您正在使用Cloud SQL JDBC SocketFactory for Cloud SQL

  1. 您应该创建一个测试service account,并为其提供执行测试所需的任何权限。要连接到Cloud SQL,对于与Cloud SQL实例相同的项目,它至少需要“ Cloud SQL客户端”角色
  2. Cloud SQL SF使用Application Default Credentials(ADC)策略来确定要使用的身份验证。这意味着它首先寻找凭据的地方是GOOGLE_APPLICATION_CREDENTIALS env var,它应该是测试服务帐户密钥的路径。