Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 51 additions & 7 deletions artifactory/commands/buildinfo/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ package buildinfo
import (
"errors"
"fmt"
evidenceCli "github.com/jfrog/jfrog-cli-artifactory/evidence/cli"
"github.com/jfrog/jfrog-cli-artifactory/evidence/evidenceproviders"
"github.com/jfrog/jfrog-cli-core/v2/artifactory/utils/commandsummary"
"github.com/jfrog/jfrog-cli-core/v2/common/commands"
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
"net/url"
"os"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -137,11 +142,9 @@ func (bpc *BuildPublishCommand) Run() error {
}
if found {
buildNumbersFrequency := CalculateBuildNumberFrequency(buildRuns)
if frequency, ok := buildNumbersFrequency[buildNumber]; ok {
err = servicesManager.DeleteBuildInfo(buildInfo, project, frequency)
if err != nil {
return err
}
err = servicesManager.DeleteBuildInfo(buildInfo, project, buildNumbersFrequency[buildNumber])
if err != nil {
return err
}
}
}
Expand Down Expand Up @@ -177,9 +180,50 @@ func (bpc *BuildPublishCommand) Run() error {
log.Info(logMsg + " Browse it in Artifactory under " + buildLink)
return nil
}

log.Info(logMsg)
return logJsonOutput(buildLink)
err = logJsonOutput(buildLink)
if err != nil {
return err
}
// check configuration to create evidence.
evidenceConfig, err := evidenceproviders.GetConfig()
if err != nil {
return logErrorAndReturn(err)
}
buildPublishConfig := &evidenceproviders.BuildPublishConfig{}
// validate evidence configuration to proceed to create evidence.
if evidenceBuildPublishConfig, ok := evidenceConfig["buildPublish"]; ok && evidenceBuildPublishConfig != nil {
if err := evidenceBuildPublishConfig.Decode(buildPublishConfig); err != nil {
return logErrorAndReturn(err)
}
if buildPublishConfig == nil || !buildPublishConfig.IsEnabled() {
log.Warn("Evidence configuration for build publish is not enabled. Skipping evidence creation.")
return nil
}
err := buildPublishConfig.Validate()
if err != nil {
return logErrorAndReturn(err)
}
os.ExpandEnv(buildPublishConfig.KeyPath)
ctx := &components.Context{}
ctx.AddStringFlag("build-name", buildInfo.Name)
ctx.AddStringFlag("build-number", buildInfo.Number)
ctx.AddStringFlag("predicate-type", buildPublishConfig.EvidenceProvider)
ctx.AddStringFlag("key", os.ExpandEnv(buildPublishConfig.KeyPath))
ctx.AddStringFlag("key-alias", buildPublishConfig.KeyAlias)
buildInfoEvidenceCMD := evidenceCli.NewEvidenceBuildCommand(ctx, commands.Exec)
evidenceCli.PlatformToEvidenceUrls(bpc.serverDetails)
err = buildInfoEvidenceCMD.CreateEvidence(ctx, bpc.serverDetails)
return logErrorAndReturn(err)
}
return nil
}

func logErrorAndReturn(err error) error {
if err != nil {
log.Error(err)
}
return nil
}

// CalculateBuildNumberFrequency since the build number is not unique, we need to calculate the frequency of each build number
Expand Down
66 changes: 54 additions & 12 deletions evidence/cli/command_cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@ package cli

import (
"errors"
"github.com/jfrog/jfrog-cli-artifactory/evidence/cli/docs/config"
"github.com/jfrog/jfrog-cli-artifactory/evidence/cli/docs/create"
"github.com/jfrog/jfrog-cli-artifactory/evidence/evidenceproviders"
commonCliUtils "github.com/jfrog/jfrog-cli-core/v2/common/cliutils"
"github.com/jfrog/jfrog-cli-core/v2/common/commands"
pluginsCommon "github.com/jfrog/jfrog-cli-core/v2/plugins/common"
"github.com/jfrog/jfrog-cli-core/v2/plugins/components"
coreConfig "github.com/jfrog/jfrog-cli-core/v2/utils/config"
coreUtils "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
"github.com/jfrog/jfrog-client-go/utils"
"github.com/jfrog/jfrog-client-go/utils/errorutils"
"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
"gopkg.in/yaml.v3"
"os"
"path/filepath"
"strings"
)

Expand All @@ -25,6 +29,14 @@ func GetCommands() []components.Command {
Arguments: create.GetArguments(),
Action: createEvidence,
},
{
Name: "generate-config",
Aliases: []string{"gc"},
Flags: GetCommandFlags(GenerateConfig),
Description: config.GetDescription(),
Arguments: create.GetArguments(),
Action: generateEvidenceProviderConfig,
},
}
}

Expand Down Expand Up @@ -60,6 +72,46 @@ func createEvidence(ctx *components.Context) error {
return command.CreateEvidence(ctx, serverDetails)
}

func generateEvidenceProviderConfig(ctx *components.Context) error {
if show, err := pluginsCommon.ShowCmdHelpIfNeeded(ctx, ctx.Arguments); show || err != nil {
return err
}
if len(ctx.Arguments) != 1 {
return pluginsCommon.WrongNumberOfArgumentsHandler(ctx)
}
globalFlag := ctx.GetBoolFlagValue("global")
evidenceDir, err := evidenceproviders.GetEvidenceDir(globalFlag)
if err != nil {
return err
}
var evidenceConfigMap map[string]*yaml.Node
evidenceFile := filepath.Join(evidenceDir, "evidence.yaml")
if ok, _ := fileutils.IsFileExists(evidenceFile, false); ok {
evidenceConfigMap, err = evidenceproviders.LoadConfig(evidenceFile)
if err != nil {
return err
}
}
evidenceConfig := &evidenceproviders.EvidenceConfig{}
evidenceProviders := strings.Split(ctx.GetArgumentAt(0), ",")
for _, ep := range evidenceProviders {
evidenceProvider := strings.TrimSpace(ep)
if strings.EqualFold(evidenceProvider, "sonar") {
err = CreateSonarConfig(evidenceConfigMap["sonar"], evidenceConfig)
if err != nil {
return err
}
}
if strings.EqualFold(evidenceProvider, "buildPublish") {
err = CreateBuildPublishConfig(evidenceConfigMap["buildPublish"], evidenceConfig)
if err != nil {
return err
}
}
}
return WriteConfigFile(globalFlag, evidenceConfig)
}

func validateCreateEvidenceCommonContext(ctx *components.Context) error {
if show, err := pluginsCommon.ShowCmdHelpIfNeeded(ctx, ctx.Arguments); show || err != nil {
return err
Expand All @@ -69,10 +121,6 @@ func validateCreateEvidenceCommonContext(ctx *components.Context) error {
return pluginsCommon.WrongNumberOfArgumentsHandler(ctx)
}

if !ctx.IsFlagSet(predicate) || assertValueProvided(ctx, predicate) != nil {
return errorutils.CheckErrorf("'predicate' is a mandatory field for creating evidence: --%s", predicate)
}

if !ctx.IsFlagSet(predicateType) || assertValueProvided(ctx, predicateType) != nil {
return errorutils.CheckErrorf("'predicate-type' is a mandatory field for creating evidence: --%s", predicateType)
}
Expand Down Expand Up @@ -166,7 +214,7 @@ func evidenceDetailsByFlags(ctx *components.Context) (*coreConfig.ServerDetails,
if serverDetails.Url == "" {
return nil, errors.New("platform URL is mandatory for evidence commands")
}
platformToEvidenceUrls(serverDetails)
PlatformToEvidenceUrls(serverDetails)

if serverDetails.GetUser() != "" && serverDetails.GetPassword() != "" {
return nil, errors.New("evidence service does not support basic authentication")
Expand All @@ -175,12 +223,6 @@ func evidenceDetailsByFlags(ctx *components.Context) (*coreConfig.ServerDetails,
return serverDetails, nil
}

func platformToEvidenceUrls(rtDetails *coreConfig.ServerDetails) {
rtDetails.ArtifactoryUrl = utils.AddTrailingSlashIfNeeded(rtDetails.Url) + "artifactory/"
rtDetails.EvidenceUrl = utils.AddTrailingSlashIfNeeded(rtDetails.Url) + "evidence/"
rtDetails.MetadataUrl = utils.AddTrailingSlashIfNeeded(rtDetails.Url) + "metadata/"
}

func assertValueProvided(c *components.Context, fieldName string) error {
if c.GetStringFlagValue(fieldName) == "" {
return errorutils.CheckErrorf("the --%s option is mandatory", fieldName)
Expand Down
13 changes: 13 additions & 0 deletions evidence/cli/docs/config/help.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package config

import "github.com/jfrog/jfrog-cli-core/v2/plugins/components"

func GetDescription() string {
return "Generate Evidence Provider Configuration."
}

func GetArguments() []components.Argument {
return []components.Argument{
{Name: "sonar", Description: "Generate configuration for SonarQube."},
}
}
23 changes: 22 additions & 1 deletion evidence/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ const (
subjectSha256 = "subject-sha256"
key = "key"
keyAlias = "key-alias"

// Evidence config flags
GenerateConfig = "generate-config"
reportTaskFile = "report-task-file"
maxRetries = "max-retries"
retryInterval = "retry-interval"
proxy = "proxy"
evdConfigURL = "evd-config-url"
)

// Flag keys mapped to their corresponding components.Flag definition.
Expand All @@ -54,13 +62,19 @@ var flagsMap = map[string]components.Flag{
packageVersion: components.NewStringFlag(packageVersion, "Package version.", func(f *components.StringFlag) { f.Mandatory = false }),
packageRepoName: components.NewStringFlag(packageRepoName, "Package repository Name.", func(f *components.StringFlag) { f.Mandatory = false }),

predicate: components.NewStringFlag(predicate, "Path to the predicate, arbitrary JSON.", func(f *components.StringFlag) { f.Mandatory = true }),
predicate: components.NewStringFlag(predicate, "Path to the predicate, arbitrary JSON.", func(f *components.StringFlag) { f.Mandatory = false }),
predicateType: components.NewStringFlag(predicateType, "Type of the predicate.", func(f *components.StringFlag) { f.Mandatory = true }),
markdown: components.NewStringFlag(markdown, "Markdown of the predicate.", func(f *components.StringFlag) { f.Mandatory = false }),
subjectRepoPath: components.NewStringFlag(subjectRepoPath, "Full path to some subject' location.", func(f *components.StringFlag) { f.Mandatory = false }),
subjectSha256: components.NewStringFlag(subjectSha256, "Subject checksum sha256.", func(f *components.StringFlag) { f.Mandatory = false }),
key: components.NewStringFlag(key, "Path to a private key that will sign the DSSE. Supported keys: 'ecdsa','rsa' and 'ed25519'.", func(f *components.StringFlag) { f.Mandatory = false }),
keyAlias: components.NewStringFlag(keyAlias, "Key alias", func(f *components.StringFlag) { f.Mandatory = false }),

evdConfigURL: components.NewStringFlag(url, "Sonar host URL", func(f *components.StringFlag) { f.Mandatory = false }),
reportTaskFile: components.NewStringFlag(reportTaskFile, "Path to the report task file", func(f *components.StringFlag) { f.Mandatory = false }),
maxRetries: components.NewStringFlag(maxRetries, "Maximum number of retries to create evidence", func(f *components.StringFlag) { f.Mandatory = false }),
retryInterval: components.NewStringFlag(retryInterval, "Interval between retries in seconds", func(f *components.StringFlag) { f.Mandatory = false }),
proxy: components.NewStringFlag(proxy, "Proxy URL", func(f *components.StringFlag) { f.Mandatory = false }),
}

var commandFlags = map[string][]string{
Expand All @@ -85,6 +99,13 @@ var commandFlags = map[string][]string{
key,
keyAlias,
},
GenerateConfig: {
evdConfigURL,
reportTaskFile,
maxRetries,
retryInterval,
proxy,
},
}

func GetCommandFlags(cmdKey string) []components.Flag {
Expand Down
Loading