'Nexus unauthorized access using sbt

I am trying to build a sbt Scala application on AWS CodeBuild. I need to use the corporate Nexus in order to download packages. However, I keep getting unauthorised access. What am I setting up wrong?

buildspec.yaml containing the UNIX commands I need to run in order to setup the nexus credentials, sbt options, etc.

version: 0.2

env:
  variables:
    # JAVA_HOME: "/usr/lib/jvm/java-8-openjdk-amd64"
    SBT_OPTS: "-Djavax.net.ssl.trustStore=nexusprod-all.jks -Dsbt.repository.config=repositories -Dsbt.repository.secure=true -Dsbt.override.build.repos=true -Dsbt.boot.credentials=/root/.sbt/.credentials"
phases:
  install:
    commands:
      - echo Entered the install phase ..
    finally:
      - echo This always runs even if the update or install command fails
  pre_build:
    commands:
      - echo Copying repositories and creating credentials
      - cp repositories /root/.sbt/
      - USERNAME=$(aws secretsmanager get-secret-value --secret-id nexus_secret --query SecretString --output text|jq -r .username)
      - PASSWORD=$(aws secretsmanager get-secret-value --secret-id nexus_secret --query SecretString --output text|jq -r .password)
      - echo "realm=Sonatype Nexus" >> /root/.sbt/.credentials
      - echo "host=nexus-eu.windmill.local" >> /root/.sbt/.credentials 
      - echo "user=${USERNAME}" >> /root/.sbt/.credentials
      - echo "password=${PASSWORD}" >> /root/.sbt/.credentials
      - cat /root/.sbt/.credentials
    # NEXUS CONNECTION WORKS, USE BELOW TO TEST IT.
    #   - export NEXUS_TOKEN=$(aws secretsmanager get-secret-value --secret-id nexus_secret --query SecretString --output text|jq -r .token)
    #   - export USERNAME=$(aws secretsmanager get-secret-value --secret-id nexus_secret --query SecretString --output text|jq -r .username)
    #   - export PASSWORD=$(aws secretsmanager get-secret-value --secret-id nexus_secret --query SecretString --output text|jq -r .password)
    #   - npm config set registry=https://nexus-eu.windmill.local/repository/npm-proxy/
    #   - npm set strict-ssl false
    #   - npm set always-auth=true
    #   - npm set [email protected]
    #   - npm set _auth=$NEXUS_TOKEN
    #   - pip config --user set global.index-url https://$USERNAME:[email protected]/repository/pypi-proxy/simple
    #   - pip config --user set global.index https://nexus-eu.windmill.local/repository/pypi-proxy/pypi
    #   - pip config --user set global.trusted-host nexus-eu.windmill.local
    #   - pip install black     
  build:
    commands:
      - echo Build started on `date`
      - sbt build
  post_build:
    commands:
      - echo Build completed on `date`
      - echo "$(cat /root/.sbt/boot/update.log)"
artifacts:
  files:
    - aac-cdp-glue-bl/src/main/scala/daan/cdp/etl/glue/Main.scala
    - aac-cdp-glue-bl/target/*/aac-cdp-glue.jar
  discard-paths: yes
cache:
  paths:
    - '/root/.sbt/**/*'

As you can see from the npm commented-out commands, when I use those to connect to nexus I am able to download packages.

build.sbt file

import Dependencies._

organization := "XYZ"

ThisBuild / version := "0.1"

ThisBuild / scalaVersion := "2.12.14"

credentials += Credentials("root" / ".sbt" / ".credentials")

lazy val testSettings = Seq(
  Test / testOptions := Seq(
    Tests.Argument(
      TestFrameworks.ScalaTest,
      "-oDS",
      "-u",
      "target/test-reports",
      "-h",
      (target.value / "test-reports").getAbsolutePath
    )
  )
)

lazy val root =
  project
    .in(file("."))
    .settings(name := "aac-cdp-glue")
    .aggregate(`aac-cdp-glue-bl`, `aac-cdp-glue-unit-tests`)

lazy val `aac-cdp-glue-bl` = project
  .in(file("aac-cdp-glue-bl"))
  .settings(
    name := "aac-cdp-glue-bl",
    libraryDependencies ++= Seq(
      Aws.glueSdk,
      Enumeratum.core,
      Refined.core
    ) ++ Cats.all ++ Circe.all ++ Decline.all ++ Spark3.all,
    resolvers += "Aws".at("https://aws-glue-etl-artifacts.s3.amazonaws.com/release"),
    assembly / assemblyOption := (assembly / assemblyOption).value.copy(includeScala = false),
    assembly / assemblyJarName := "aac-cdp-glue.jar",
    assembly / assemblyMergeStrategy := {
      case PathList("javax", "servlet", xs @ _*)        => MergeStrategy.last
      case PathList("javax", "activation", xs @ _*)     => MergeStrategy.last
      case PathList("org", "apache", xs @ _*)           => MergeStrategy.last
      case PathList("com", "google", xs @ _*)           => MergeStrategy.last
      case PathList("com", "esotericsoftware", xs @ _*) => MergeStrategy.last
      case PathList("com", "codahale", xs @ _*)         => MergeStrategy.last
      case PathList("com", "yammer", xs @ _*)           => MergeStrategy.last
      case "about.html"                                 => MergeStrategy.rename
      case "META-INF/ECLIPSEF.RSA"                      => MergeStrategy.last
      case "META-INF/mailcap"                           => MergeStrategy.last
      case "META-INF/mimetypes.default"                 => MergeStrategy.last
      case "plugin.properties"                          => MergeStrategy.last
      case "log4j.properties"                           => MergeStrategy.last
      case x =>
        val oldStrategy = (assembly / assemblyMergeStrategy).value
        oldStrategy(x)
    }
  )

lazy val `aac-cdp-glue-unit-tests` = project
  .in(file("aac-cdp-glue-unit-tests"))
  .settings(
    name := "aac-cdp-glue-unit-tests",
    libraryDependencies ++= Seq(
      Refined.core % Test,
      Refined.scalaCheck
    ) ++ Cats.all ++ Circe.all ++ Spark3.all ++ TestLibs.all,
    assembly / test := {}
  )
  .dependsOn(`aac-cdp-glue-bl` % "test -> compile")

addCommandAlias("build", "; clean; test; aac-cdp-glue-bl/assembly")

project/plugins.sbt

addSbtPlugin("com.eed3si9n"  % "sbt-assembly" % "0.14.6")

repositories file

[repositories]
  local
  my-maven-proxy-releases: https://nexus-eu.windmill.local/repository/public/
  my-maven-releases: https://nexus-eu.windmill.local/repository/public/,[organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]

build.properties file

sbt.version=1.6.1

project/Dependencies.scala (don't think this is related)

import sbt._

object Dependencies {

  object Aws {
    val glueSdk = "com.amazonaws" % "AWSGlueETL" % "3.0.0" % Provided
  }

  object Cats {
    private val effectVersion =
      "2.1.1" // Do not upgrade! Spark 3.1.1 depends on cats-kernel_2.12-2.0.0-M4 (compatible with cats-kernel_2.12-2.1.1)

    val effect = "org.typelevel" %% "cats-effect" % effectVersion

    val all = Seq(effect)
  }

  object Circe {
    private val version = "0.13.0"

    val core    = "io.circe" %% "circe-core"    % version
    val parser  = "io.circe" %% "circe-parser"  % version
    val generic = "io.circe" %% "circe-generic" % version

    val all = Seq(core, generic, parser)
  }

  object Decline {
    val version = "1.2.0" // Do not upgrade! This version depends on cats 2.1.1

    val core       = "com.monovore" %% "decline"            % version
    val effect     = "com.monovore" %% "decline-effect"     % version
    val enumeratum = "com.monovore" %% "decline-enumeratum" % version
    val refined    = "com.monovore" %% "decline-refined"    % version

    val all = Seq(core, effect, enumeratum, refined)
  }

  object Enumeratum {
    val core = "com.beachape" %% "enumeratum" % "1.7.0"
  }

  object Refined {
    private val version = "0.9.21"

    val core       = "eu.timepit" %% "refined"            % version
    val scalaCheck = "eu.timepit" %% "refined-scalacheck" % version % Test
  }

  object Spark3 {
    private val sparkVersion =
      "3.1.1" // Beware! This version depends on cats-kernel_2.12-2.0.0-M4 (see above)

    val core = "org.apache.spark" %% "spark-core" % sparkVersion % Provided
    val sql  = "org.apache.spark" %% "spark-sql"  % sparkVersion % Provided

    val all = Seq(core, sql)
  }

  object TestLibs {
    val scalaTest     = "org.scalatest"     %% "scalatest"                % "3.2.2"       % Test
    val scalaCheck    = "org.scalacheck"    %% "scalacheck"               % "1.15.4"      % Test
    val scalaTestPlus = "org.scalatestplus" %% "scalatestplus-scalacheck" % "3.1.0.0-RC2" % Test

    val all = Seq(scalaTest, scalaCheck, scalaTestPlus)
  }
}

I get an unauthorised error when trying to download the plugins (sbt-assembly). Note that if I remove the plugin from plugins.sbt I get the same unauthorised error on the subsequent Scala dependencies that I need to get from Nexus.

[Container] 2022/04/14 15:47:53 Waiting for agent ping
[Container] 2022/04/14 15:48:53 Waiting for DOWNLOAD_SOURCE
[Container] 2022/04/14 15:48:54 Phase is DOWNLOAD_SOURCE
[Container] 2022/04/14 15:48:54 CODEBUILD_SRC_DIR=/codebuild/output/src246710942/src
[Container] 2022/04/14 15:48:54 YAML location is /codebuild/output/src246710942/src/buildspec.yml
[Container] 2022/04/14 15:48:54 Processing environment variables
[Container] 2022/04/14 15:48:54 No runtime version selected in buildspec.
[Container] 2022/04/14 15:48:56 Moving to directory /codebuild/output/src246710942/src
[Container] 2022/04/14 15:48:56 Expanded cache path /root/.sbt/**/*
[Container] 2022/04/14 15:48:56 Configuring ssm agent with target id: codebuild:20483d62-bbbc-409d-b677-d6bbbe8149bb
[Container] 2022/04/14 15:48:56 Successfully updated ssm agent configuration
[Container] 2022/04/14 15:48:56 Registering with agent
[Container] 2022/04/14 15:48:56 Phases found in YAML: 4
[Container] 2022/04/14 15:48:56  INSTALL: 1 commands
[Container] 2022/04/14 15:48:56  PRE_BUILD: 9 commands
[Container] 2022/04/14 15:48:56  BUILD: 2 commands
[Container] 2022/04/14 15:48:56  POST_BUILD: 2 commands
[Container] 2022/04/14 15:48:56 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
[Container] 2022/04/14 15:48:56 Phase context status code:  Message: 
[Container] 2022/04/14 15:48:56 Entering phase INSTALL
[Container] 2022/04/14 15:48:56 Running command echo Entered the install phase ..
Entered the install phase ..

[Container] 2022/04/14 15:48:56 Running command echo This always runs even if the update or install command fails
This always runs even if the update or install command fails

[Container] 2022/04/14 15:48:56 Phase complete: INSTALL State: SUCCEEDED
[Container] 2022/04/14 15:48:56 Phase context status code:  Message: 
[Container] 2022/04/14 15:48:56 Entering phase PRE_BUILD
[Container] 2022/04/14 15:48:56 Running command echo Copying repositories and creating credentials
Copying repositories and creating credentials

[Container] 2022/04/14 15:48:56 Running command cp repositories /root/.sbt/

[Container] 2022/04/14 15:48:56 Running command USERNAME=$(aws secretsmanager get-secret-value --secret-id nexus_secret --query SecretString --output text|jq -r .username)

[Container] 2022/04/14 15:49:00 Running command PASSWORD=$(aws secretsmanager get-secret-value --secret-id nexus_secret --query SecretString --output text|jq -r .password)

[Container] 2022/04/14 15:49:01 Running command echo "realm=Sonatype Nexus" >> /root/.sbt/.credentials

[Container] 2022/04/14 15:49:01 Running command echo "host=nexus-eu.windmill.local" >> /root/.sbt/.credentials

[Container] 2022/04/14 15:49:01 Running command echo "user=${USERNAME}" >> /root/.sbt/.credentials

[Container] 2022/04/14 15:49:01 Running command echo "password=${PASSWORD}" >> /root/.sbt/.credentials

[Container] 2022/04/14 15:49:01 Running command cat /root/.sbt/.credentials
realm=Sonatype Nexus
host=nexus-eu.windmill.local
user=<OBSCURED>
password=<OBSCURED>

[Container] 2022/04/14 15:49:01 Phase complete: PRE_BUILD State: SUCCEEDED
[Container] 2022/04/14 15:49:01 Phase context status code:  Message: 
[Container] 2022/04/14 15:49:01 Entering phase BUILD
[Container] 2022/04/14 15:49:01 Running command echo Build started on `date`
Build started on Thu Apr 14 15:49:01 UTC 2022

[Container] 2022/04/14 15:49:01 Running command sbt build
[info] welcome to sbt 1.6.1 (Amazon.com Inc. Java 11.0.14.1)
[info] loading settings for project src-build from plugins.sbt ...
[info] loading project definition from /codebuild/output/src246710942/src/project
[warn] 
[warn]  Note: Some unresolved dependencies have extra attributes.  Check that these dependencies exist with the requested attributes.
[warn]      com.eed3si9n:sbt-assembly:0.14.6 (sbtVersion=1.0, scalaVersion=2.12)
[warn] 
[warn]  Note: Unresolved dependencies path:
[error] sbt.librarymanagement.ResolveException: Error downloading com.eed3si9n:sbt-assembly;sbtVersion=1.0;scalaVersion=2.12:0.14.6
[error]   Not found
[error]   Not found
[error]   not found: /root/.ivy2/localcom.eed3si9n/sbt-assembly/scala_2.12/sbt_1.0/0.14.6/ivys/ivy.xml
[error]   unauthorized: https://nexus-eu.windmill.local/repository/public/com/eed3si9n/sbt-assembly_2.12_1.0/0.14.6/sbt-assembly-0.14.6.pom (Sonatype Nexus Repository Manager)
[error]   unauthorized: https://nexus-eu.windmill.local/repository/public/com.eed3si9n/sbt-assembly/scala_2.12/sbt_1.0/0.14.6/ivys/ivy.xml (Sonatype Nexus Repository Manager)
[error]     at lmcoursier.CoursierDependencyResolution.unresolvedWarningOrThrow(CoursierDependencyResolution.scala:345)
[error]     at lmcoursier.CoursierDependencyResolution.$anonfun$update$38(CoursierDependencyResolution.scala:314)
[error]     at scala.util.Either$LeftProjection.map(Either.scala:573)
[error]     at lmcoursier.CoursierDependencyResolution.update(CoursierDependencyResolution.scala:314)
[error]     at sbt.librarymanagement.DependencyResolution.update(DependencyResolution.scala:60)
[error]     at sbt.internal.LibraryManagement$.resolve$1(LibraryManagement.scala:59)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$12(LibraryManagement.scala:133)
[error]     at sbt.util.Tracked$.$anonfun$lastOutput$1(Tracked.scala:73)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$20(LibraryManagement.scala:146)
[error]     at scala.util.control.Exception$Catch.apply(Exception.scala:228)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$11(LibraryManagement.scala:146)
[error]     at sbt.internal.LibraryManagement$.$anonfun$cachedUpdate$11$adapted(LibraryManagement.scala:127)
[error]     at sbt.util.Tracked$.$anonfun$inputChangedW$1(Tracked.scala:219)
[error]     at sbt.internal.LibraryManagement$.cachedUpdate(LibraryManagement.scala:160)
[error]     at sbt.Classpaths$.$anonfun$updateTask0$1(Defaults.scala:3690)
[error]     at scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error]     at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error]     at sbt.std.Transform$$anon$4.work(Transform.scala:68)
[error]     at sbt.Execute.$anonfun$submit$2(Execute.scala:282)
[error]     at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
[error]     at sbt.Execute.work(Execute.scala:291)
[error]     at sbt.Execute.$anonfun$submit$1(Execute.scala:282)
[error]     at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
[error]     at sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
[error]     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]     at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
[error]     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
[error]     at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[error]     at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[error]     at java.base/java.lang.Thread.run(Thread.java:829)
[error] (update) sbt.librarymanagement.ResolveException: Error downloading com.eed3si9n:sbt-assembly;sbtVersion=1.0;scalaVersion=2.12:0.14.6
[error]   Not found
[error]   Not found
[error]   not found: /root/.ivy2/localcom.eed3si9n/sbt-assembly/scala_2.12/sbt_1.0/0.14.6/ivys/ivy.xml
[error]   unauthorized: https://nexus-eu.windmill.local/repository/public/com/eed3si9n/sbt-assembly_2.12_1.0/0.14.6/sbt-assembly-0.14.6.pom (Sonatype Nexus Repository Manager)
[error]   unauthorized: https://nexus-eu.windmill.local/repository/public/com.eed3si9n/sbt-assembly/scala_2.12/sbt_1.0/0.14.6/ivys/ivy.xml (Sonatype Nexus Repository Manager)
[warn] Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? (default: r)

[Container] 2022/04/14 15:49:19 Command did not exit successfully sbt build exit status 1
[Container] 2022/04/14 15:49:19 Phase complete: BUILD State: FAILED
[Container] 2022/04/14 15:49:19 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: sbt build. Reason: exit status 1
[Container] 2022/04/14 15:49:19 Entering phase POST_BUILD
[Container] 2022/04/14 15:49:19 Running command echo Build completed on `date`
Build completed on Thu Apr 14 15:49:19 UTC 2022

[Container] 2022/04/14 15:49:19 Running command echo "$(cat /root/.sbt/boot/update.log)"


[Container] 2022/04/14 15:49:19 Phase complete: POST_BUILD State: SUCCEEDED
[Container] 2022/04/14 15:49:19 Phase context status code:  Message: 
[Container] 2022/04/14 15:49:19 Expanding base directory path: .
[Container] 2022/04/14 15:49:19 Assembling file list
[Container] 2022/04/14 15:49:19 Expanding .
[Container] 2022/04/14 15:49:19 Expanding file paths for base directory .
[Container] 2022/04/14 15:49:19 Assembling file list
[Container] 2022/04/14 15:49:19 Expanding aac-cdp-glue-bl/src/main/scala/daan/cdp/etl/glue/Main.scala
[Container] 2022/04/14 15:49:19 Expanding aac-cdp-glue-bl/target/*/aac-cdp-glue.jar
[Container] 2022/04/14 15:49:19 Found 1 file(s)
[Container] 2022/04/14 15:49:19 Phase complete: UPLOAD_ARTIFACTS State: SUCCEEDED
[Container] 2022/04/14 15:49:19 Phase context status code:  Message:

Note that I have tried to set the credentials both inline in the build.sbt or via the credentials file. Same error. I can reach Nexus (npm proxy) though. What am I doing wrong?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source