Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read and publish CVE information during anago/stage #1996

Merged
merged 10 commits into from
Apr 14, 2021
2 changes: 0 additions & 2 deletions cmd/krel/cmd/changelog_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ const patchReleaseExpectedContent = `## Changes by Kind
- Restores compatibility of kube-scheduler with clusters that do not enable the events.k8s.io/v1beta1 API ([#84465](https://github.com/kubernetes/kubernetes/pull/84465), [@yastij](https://github.com/yastij)) [SIG API Machinery and Scheduling]
- Switched intstr.Type to sized integer to follow API guidelines and improve compatibility with proto libraries ([#83956](https://github.com/kubernetes/kubernetes/pull/83956), [@liggitt](https://github.com/liggitt)) [SIG API Machinery]
- Update Cluster Autoscaler version to 1.16.2 (CA release docs: https://github.com/kubernetes/autoscaler/releases/tag/cluster-autoscaler-1.16.2) ([#84038](https://github.com/kubernetes/kubernetes/pull/84038), [@losipiuk](https://github.com/losipiuk)) [SIG Cluster Lifecycle]
- Update to use go1.12.12 ([#84064](https://github.com/kubernetes/kubernetes/pull/84064), [@cblecker](https://github.com/cblecker)) [SIG Release and Testing]
- Upgrade to etcd client 3.3.17 to fix bug where etcd client does not parse IPv6 addresses correctly when members are joining, and to fix bug where failover on multi-member etcd cluster fails certificate check on DNS mismatch ([#83968](https://github.com/kubernetes/kubernetes/pull/83968), [@jpbetz](https://github.com/jpbetz)) [SIG API Machinery and Cloud Provider]`

const patchReleaseDeps = `## Dependencies
Expand Down Expand Up @@ -216,7 +215,6 @@ const patchReleaseExpectedHTML = `<!DOCTYPE html>
<li>Restores compatibility of kube-scheduler with clusters that do not enable the events.k8s.io/v1beta1 API (<a href="https://github.com/kubernetes/kubernetes/pull/84465">#84465</a>, <a href="https://github.com/yastij">@yastij</a>) [SIG API Machinery and Scheduling]</li>
<li>Switched intstr.Type to sized integer to follow API guidelines and improve compatibility with proto libraries (<a href="https://github.com/kubernetes/kubernetes/pull/83956">#83956</a>, <a href="https://github.com/liggitt">@liggitt</a>) [SIG API Machinery]</li>
<li>Update Cluster Autoscaler version to 1.16.2 (CA release docs: <a href="https://github.com/kubernetes/autoscaler/releases/tag/cluster-autoscaler-1.16.2">https://github.com/kubernetes/autoscaler/releases/tag/cluster-autoscaler-1.16.2</a>) (<a href="https://github.com/kubernetes/kubernetes/pull/84038">#84038</a>, <a href="https://github.com/losipiuk">@losipiuk</a>) [SIG Cluster Lifecycle]</li>
<li>Update to use go1.12.12 (<a href="https://github.com/kubernetes/kubernetes/pull/84064">#84064</a>, <a href="https://github.com/cblecker">@cblecker</a>) [SIG Release and Testing]</li>
<li>Upgrade to etcd client 3.3.17 to fix bug where etcd client does not parse IPv6 addresses correctly when members are joining, and to fix bug where failover on multi-member etcd cluster fails certificate check on DNS mismatch (<a href="https://github.com/kubernetes/kubernetes/pull/83968">#83968</a>, <a href="https://github.com/jpbetz">@jpbetz</a>) [SIG API Machinery and Cloud Provider]</li>
</ul>
<h2>Dependencies</h2>
Expand Down
11 changes: 6 additions & 5 deletions cmd/krel/cmd/changelog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ import (

func (s *sut) getChangelogOptions(tag string) *changelog.Options {
return &changelog.Options{
RepoPath: s.repo.Dir(),
ReplayDir: filepath.Join(testDataDir, "changelog-"+tag),
Tag: tag,
Tars: ".",
Branch: git.DefaultBranch,
RepoPath: s.repo.Dir(),
ReplayDir: filepath.Join(testDataDir, "changelog-"+tag),
Tag: tag,
Tars: ".",
Branch: git.DefaultBranch,
CloneCVEMaps: false,
}
}

Expand Down
1 change: 1 addition & 0 deletions pkg/anago/stage.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ func (d *DefaultStage) GenerateChangelog() error {
HTMLFile: releaseNotesHTMLFile,
JSONFile: releaseNotesJSONFile,
Dependencies: true,
CloneCVEMaps: true,
Tars: filepath.Join(
gitRoot,
fmt.Sprintf("%s-%s", release.BuildDir, d.state.versions.Prime()),
Expand Down
16 changes: 16 additions & 0 deletions pkg/changelog/changelog.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type Options struct {
JSONFile string
RecordDir string
ReplayDir string
CVEDataDir string
CloneCVEMaps bool
Dependencies bool
}

Expand Down Expand Up @@ -158,6 +160,14 @@ func (c *Changelog) Run() error {
}
}
} else {
if c.options.CloneCVEMaps {
cveDir, err := c.impl.CloneCVEData()
if err != nil {
return errors.Wrap(err, "getting cve data maps")
}
c.options.CVEDataDir = cveDir
}

// A patch version, let’s just use the previous patch
startTag := util.SemverToTagString(semver.Version{
Major: tag.Major, Minor: tag.Minor, Patch: tag.Patch - 1,
Expand Down Expand Up @@ -244,6 +254,12 @@ func (c *Changelog) generateReleaseNotes(
notesOptions.ReplayDir = c.options.ReplayDir
notesOptions.Pull = false

if c.options.CVEDataDir != "" {
notesOptions.MapProviderStrings = append(
notesOptions.MapProviderStrings, c.options.CVEDataDir,
)
}

if err := c.impl.ValidateAndFinish(notesOptions); err != nil {
return "", "", errors.Wrap(err, "validating notes options")
}
Expand Down
26 changes: 26 additions & 0 deletions pkg/changelog/changelog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,32 @@ func TestRun(t *testing.T) {
},
shouldErr: true,
},
{ // CloneCVEData returns error
prepare: func(mock *changelogfakes.FakeImpl, o *changelog.Options) {
o.CloneCVEMaps = true
mock.TagStringToSemverReturns(semver.Version{
Major: 1,
Minor: 19,
Patch: 3,
}, nil)
mock.CloneCVEDataReturns("", err)
},
shouldErr: true,
},
{ // CloneCVEData returns empty string
prepare: func(mock *changelogfakes.FakeImpl, o *changelog.Options) {
o.CloneCVEMaps = true
mock.TagStringToSemverReturns(semver.Version{
Major: 1,
Minor: 19,
Patch: 3,
}, nil)
mock.ReadFileReturns([]byte(changelog.TocEnd), nil)
mock.GatherReleaseNotesReturns(&notes.ReleaseNotes{}, nil)
mock.CloneCVEDataReturns("", nil)
},
shouldErr: false,
},
} {
options := &changelog.Options{}
sut := changelog.New(options)
Expand Down
72 changes: 71 additions & 1 deletion pkg/changelog/changelogfakes/fake_impl.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions pkg/changelog/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ filename | sha512 hash
{{- end -}}
## Changelog since {{$PreviousRevision}}

{{with .CVEList -}}
## Important Security Information

This release contains changes that address the following vulnerabilities:
{{range .}}
### {{.ID}}: {{.Title}}

{{.Description}}

**CVSS Rating:** {{.CVSSRating}} ({{.CVSSScore}}) [{{.CVSSVector}}]({{.CalcLink}})
{{- if .TrackingIssue -}}
<br>
**Tracking Issue:** {{.TrackingIssue}}
{{- end }}

{{ end }}
{{- end -}}

{{with .NotesWithActionRequired -}}
## Urgent Upgrade Notes

Expand Down
36 changes: 36 additions & 0 deletions pkg/changelog/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,20 @@ import (
"text/template"

"github.com/blang/semver"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"sigs.k8s.io/mdtoc/pkg/mdtoc"

"k8s.io/release/pkg/cve"
"k8s.io/release/pkg/git"
"k8s.io/release/pkg/github"
"k8s.io/release/pkg/notes"
"k8s.io/release/pkg/notes/document"
"k8s.io/release/pkg/notes/options"
"k8s.io/release/pkg/object"
"sigs.k8s.io/release-utils/http"
"sigs.k8s.io/release-utils/util"
)
Expand Down Expand Up @@ -88,6 +92,7 @@ type impl interface {
Add(repo *git.Repo, filename string) error
Commit(repo *git.Repo, msg string) error
Rm(repo *git.Repo, force bool, files ...string) error
CloneCVEData() (cveDir string, err error)
}

type defaultImpl struct{}
Expand Down Expand Up @@ -215,3 +220,34 @@ func (*defaultImpl) Commit(repo *git.Repo, msg string) error {
func (*defaultImpl) Rm(repo *git.Repo, force bool, files ...string) error {
return repo.Rm(force, files...)
}

// CloneCVEData copies the CVE data maps from the release bucket
func (*defaultImpl) CloneCVEData() (cveDir string, err error) {
tmpdir, err := os.MkdirTemp(os.TempDir(), "cve-maps-")
if err != nil {
return "", errors.Wrap(err, "creating temporary dir for CVE data")
}

// Create a new GCS client
gcs := object.NewGCS()
remoteSrc, err := gcs.NormalizePath(object.GcsPrefix + filepath.Join(cve.Bucket, cve.Directory))
if err != nil {
return "", errors.Wrap(err, "normalizing cve bucket path")
}

bucketExists, err := gcs.PathExists(remoteSrc)
if err != nil {
return "", errors.Wrap(err, "checking if CVE directory exists")
}
if !bucketExists {
logrus.Warnf("CVE data maps not found in bucket location: %s", remoteSrc)
return "", nil
}

// Rsync the CVE files to the temp dir
if err := gcs.RsyncRecursive(remoteSrc, tmpdir); err != nil {
return "", errors.Wrap(err, "copying release directory to bucket")
}
logrus.Infof("Successfully synchronized CVE data maps from %s", remoteSrc)
return tmpdir, nil
}
10 changes: 5 additions & 5 deletions pkg/notes/document/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,6 @@ func New(
for _, pr := range releaseNotes.History() {
note := releaseNotes.Get(pr)

if note.DoNotPublish {
logrus.Debugf("skipping PR %d as (marked to not be published)", pr)
continue
}

if _, hasCVE := note.DataFields["cve"]; hasCVE {
logrus.Infof("Release note for PR #%d has CVE vulnerability info", note.PrNumber)

Expand All @@ -240,6 +235,11 @@ func New(
doc.CVEList = append(doc.CVEList, newcve)
}

if note.DoNotPublish {
logrus.Debugf("skipping PR %d as (marked to not be published)", pr)
continue
}

// TODO: Refactor the logic here and add testing.
if note.DuplicateKind {
kind := mapKind(highestPriorityKind(note.Kinds))
Expand Down
Loading