Skip to content

Commit 09d2f46

Browse files
authored
Upload bombon bom files directly to deptrack (WPB-6142) (#3810)
This avoids cluttering our release artifact page. And, Security gets the files where they need them.
1 parent 973951a commit 09d2f46

File tree

3 files changed

+128
-15
lines changed

3 files changed

+128
-15
lines changed

Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ full-clean: clean
6161
clean:
6262
cabal clean
6363
-rm -rf dist
64+
-rm -f "bill-of-materials.$(HELM_SEMVER).json"
6465

6566
.PHONY: clean-hint
6667
clean-hint:
@@ -543,6 +544,12 @@ kind-restart-%: .local/kind-kubeconfig
543544
helm-template-%: clean-charts charts-integration
544545
./hack/bin/helm-template.sh $(*)
545546

547+
# Ask the security team for the `DEPENDENCY_TRACK_API_KEY` (if you need it)
546548
.PHONY: upload-bombon
547549
upload-bombon:
548-
./hack/bin/bombon.hs -- "$@"
550+
nix build -f nix wireServer.allLocalPackagesBom -o "bill-of-materials.$(HELM_SEMVER).json"
551+
./hack/bin/bombon.hs -- \
552+
--bom-filepath "./bill-of-materials.$(HELM_SEMVER).json" \
553+
--project-version $(HELM_SEMVER) \
554+
--api-key $(DEPENDENCY_TRACK_API_KEY) \
555+
--auto-create
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Upload bill-of-material (BOM) files directly to the Dependency Tracker via REST.
2+
This eases the life of the security team and prevents cluttering our release
3+
artifact page.

hack/bin/bombon.hs

Lines changed: 117 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,120 @@
1-
#!/usr/bin/env -S nix -Lv run github:wireapp/ghc-flakr/ecb1f45f1549e06c92d71164e305ce501eb0e36e --extra-experimental-features flakes
2-
{-# LANGUAGE BlockArguments #-}
3-
{-# LANGUAGE ImportQualifiedPost #-}
4-
{-# LANGUAGE OverloadedStrings #-}
1+
#!/usr/bin/env -S nix -Lv run github:wireapp/ghc-flakr/99fe5a331fdd37d52043f14e5c565ac29a30bcb4
2+
{-# LANGUAGE DataKinds #-}
53

6-
import Data.Text qualified as T
7-
import Turtle
4+
import Data.Aeson
5+
import qualified Data.ByteString.Base64.Lazy as Base64
6+
import qualified Data.ByteString.Lazy.Char8 as BL
7+
import Data.Proxy
8+
import Data.Text.Lazy
9+
import Data.Text.Lazy.Encoding
10+
import GHC.Generics
11+
import qualified Network.HTTP.Client as HTTP
12+
import Network.HTTP.Client.TLS (tlsManagerSettings)
13+
import Options.Applicative
14+
import Servant.API
15+
import Servant.Client
816

17+
data Payload = Payload
18+
{ bom :: Text,
19+
projectName :: String,
20+
projectVersion :: String,
21+
autoCreate :: Bool
22+
}
23+
deriving (Generic, Show)
24+
25+
instance ToJSON Payload
26+
27+
data ApiResponse = ApiResponse
28+
{ token :: String
29+
}
30+
deriving (Generic, Show)
31+
32+
instance FromJSON ApiResponse
33+
34+
type DependenyTrackAPI =
35+
"api"
36+
:> "v1"
37+
:> "bom"
38+
:> ReqBody '[JSON] Payload
39+
:> Header "X-Api-Key" String
40+
:> Put '[JSON] ApiResponse
41+
42+
api :: Proxy DependenyTrackAPI
43+
api = Proxy
44+
45+
putBOM :: Payload -> Maybe String -> ClientM ApiResponse
46+
putBOM = client api
47+
48+
data CliOptions = CliOptions
49+
{ opBomPath :: String,
50+
opProjectName :: String,
51+
opProjectVersion :: String,
52+
opAutoCreate :: Bool,
53+
opApiKey :: String
54+
}
55+
deriving (Show)
56+
57+
cliParser :: Parser CliOptions
58+
cliParser =
59+
CliOptions
60+
<$> ( strOption
61+
( long "bom-filepath"
62+
<> short 'f'
63+
<> metavar "FILENAME"
64+
)
65+
)
66+
<*> ( strOption
67+
( long "project-name"
68+
<> short 'p'
69+
<> metavar "PROJECT_NAME"
70+
<> value "wire-server-ci"
71+
)
72+
)
73+
<*> ( strOption
74+
( long "project-version"
75+
<> short 'v'
76+
<> metavar "PROJECT_VERSION"
77+
)
78+
)
79+
<*> ( switch
80+
( long "auto-create"
81+
<> short 'c'
82+
)
83+
)
84+
<*> ( strOption
85+
( long "api-key"
86+
<> short 'k'
87+
<> metavar "API_KEY"
88+
)
89+
)
90+
91+
fullCliParser :: ParserInfo CliOptions
92+
fullCliParser =
93+
info
94+
(cliParser <**> helper)
95+
( fullDesc
96+
<> progDesc "Upload BOM files to deptrack"
97+
)
98+
99+
main :: IO ()
9100
main = do
10-
(release, repo) <- options "Upload boms" do
11-
(,)
12-
<$> optText "release" 't' "Which release tag to upload the artifacts to"
13-
<*> optText "repo" 'r' "Which repository to upload the artifacts to"
14-
let bomName = "wire-server-bom-" <> release <> ".json"
15-
ExitSuccess <- proc "nix" ["build", "-f", "nix", "wireServer.allLocalPackagesBom", "-o", bomName] mempty
16-
printf ("uploading " % s % " to release " % s % "\n") bomName ("chart/" <> release)
17-
proc "gh" ["-R", repo, "release", "upload", "chart/" <> release, bomName] mempty
101+
options <- execParser fullCliParser
102+
manager' <- HTTP.newManager tlsManagerSettings
103+
bom <- readFile $ opBomPath options
104+
let payload =
105+
Payload
106+
{ bom = toBase64Text bom,
107+
projectName = opProjectName options,
108+
projectVersion = opProjectVersion options,
109+
autoCreate = opAutoCreate options
110+
}
111+
res <-
112+
runClientM
113+
(putBOM payload ((Just . opApiKey) options))
114+
(mkClientEnv manager' (BaseUrl Https "deptrack.wire.link" 443 ""))
115+
case res of
116+
Left err -> print $ "Error: " ++ show err
117+
Right res -> print res
118+
119+
toBase64Text :: String -> Text
120+
toBase64Text = decodeUtf8 . Base64.encode . BL.pack

0 commit comments

Comments
 (0)