Skip to content

Commit

Permalink
OCPBUGS-36344: Add CIP relevant mirrors to sigstore attachement cfg
Browse files Browse the repository at this point in the history
Add icsp/idms/itms mirrors of CIP scope to /etc/containers/registries.d, so sigstore attachment will be used during the image pull and verification.

Signed-off-by: Qi Wang <qiwan@redhat.com>
  • Loading branch information
QiWang19 committed Jul 9, 2024
1 parent edfb19f commit 78f043b
Show file tree
Hide file tree
Showing 4 changed files with 331 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ func registriesConfigIgnition(templateDir string, controllerConfig *mcfgv1.Contr
return nil, fmt.Errorf("could not update policy json with new changes: %w", err)
}
// generates configuration under /etc/containers/registries.d to enable sigstore verification
sigstoreRegistriesConfigYaml, err = generateSigstoreRegistriesdConfig(clusterScopePolicies)
sigstoreRegistriesConfigYaml, err = generateSigstoreRegistriesdConfig(clusterScopePolicies, registriesTOML)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ func verifyRegistriesConfigAndPolicyJSONContents(t *testing.T, mc *mcfgv1.Machin
}

if verifyImagePoliciesRegistriesConfig {
expectedRegistriesConfd, err := generateSigstoreRegistriesdConfig(clusterScopePolicies)
expectedRegistriesConfd, err := generateSigstoreRegistriesdConfig(clusterScopePolicies, expectedRegistriesConf)
require.NoError(t, err)
foundFile := false

Expand Down Expand Up @@ -1794,3 +1794,54 @@ func TestClusterImagePolicyCreate(t *testing.T) {
})
}
}

func TestSigstoreRegistriesConfigIDMSandCIPCreate(t *testing.T) {
for _, platform := range []apicfgv1.PlatformType{apicfgv1.AWSPlatformType, apicfgv1.NonePlatformType, "unrecognized"} {
t.Run(string(platform), func(t *testing.T) {
f := newFixture(t)

cc := newControllerConfig(ctrlcommon.ControllerConfigName, platform)
mcp := helpers.NewMachineConfigPool("master", nil, helpers.MasterSelector, "v0")
mcp2 := helpers.NewMachineConfigPool("worker", nil, helpers.WorkerSelector, "v0")
imgcfg1 := newImageConfig("cluster", &apicfgv1.RegistrySources{InsecureRegistries: []string{"blah.io"}, AllowedRegistries: []string{"example.com"}, ContainerRuntimeSearchRegistries: []string{"search-reg.io"}})

cvcfg1 := newClusterVersionConfig("version", "test.io/myuser/myimage:test")
keyReg1, _ := getManagedKeyReg(mcp, nil)
keyReg2, _ := getManagedKeyReg(mcp2, nil)

mcs1 := helpers.NewMachineConfig(keyReg1, map[string]string{"node-role": "master"}, "dummy://", []ign3types.File{{}})
mcs2 := helpers.NewMachineConfig(keyReg2, map[string]string{"node-role": "worker"}, "dummy://", []ign3types.File{{}})

// idms source is the same as cip scope
idms := newIDMS("built-in", []apicfgv1.ImageDigestMirrors{
{Source: "built-in-source.example.com", Mirrors: []apicfgv1.ImageMirror{"built-in-mirror.example.com"}},
})
clusterimgPolicy := newClusterImagePolicyWithPublicKey("built-in-source.example.com", []string{"example.com"}, []byte("foo bar"))
f.ccLister = append(f.ccLister, cc)
f.mcpLister = append(f.mcpLister, mcp)
f.mcpLister = append(f.mcpLister, mcp2)
f.imgLister = append(f.imgLister, imgcfg1)
f.idmsLister = append(f.idmsLister, idms)
f.clusterImagePolicyLister = append(f.clusterImagePolicyLister, clusterimgPolicy)
f.cvLister = append(f.cvLister, cvcfg1)
f.imgObjects = append(f.imgObjects, imgcfg1)

f.expectGetMachineConfigAction(mcs1)
f.expectGetMachineConfigAction(mcs1)
f.expectGetMachineConfigAction(mcs1)
f.expectCreateMachineConfigAction(mcs1)

f.expectGetMachineConfigAction(mcs2)
f.expectGetMachineConfigAction(mcs2)
f.expectGetMachineConfigAction(mcs2)

f.expectCreateMachineConfigAction(mcs2)

f.run("")

for _, mcName := range []string{mcs1.Name, mcs2.Name} {
f.verifyRegistriesConfigAndPolicyJSONContents(t, mcName, imgcfg1, nil, idms, nil, clusterimgPolicy, cc.Spec.ReleaseImage, true, true, true)
}
})
}
}
127 changes: 121 additions & 6 deletions pkg/controller/container-runtime-config/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
storageconfig "github.com/containers/storage/pkg/config"
ign3types "github.com/coreos/ignition/v2/config/v3_4/types"
"github.com/ghodss/yaml"
"github.com/opencontainers/go-digest"
apicfgv1 "github.com/openshift/api/config/v1"
apicfgv1alpha1 "github.com/openshift/api/config/v1alpha1"
apioperatorsv1alpha1 "github.com/openshift/api/operator/v1alpha1"
Expand Down Expand Up @@ -933,17 +934,69 @@ func validateClusterImagePolicyWithAllowedBlockedRegistries(clusterScopePolicies
return nil
}

func generateSigstoreRegistriesdConfig(clusterScopePolicies map[string]signature.PolicyRequirements) ([]byte, error) {
func generateSigstoreRegistriesdConfig(clusterScopePolicies map[string]signature.PolicyRequirements, registriesTOML []byte) ([]byte, error) {
if len(clusterScopePolicies) == 0 {
return nil, nil
}

registriesDockerConfig := make(map[string]dockerConfig)
sigstoreAttachment := dockerConfig{
UseSigstoreAttachments: true,
var (
err error
tmpFile *os.File
registriesConf = sysregistriesv2.V2RegistriesConf{}
registriesDockerConfig = make(map[string]dockerConfig)
sigstoreAttachment = dockerConfig{
UseSigstoreAttachments: true,
}
)

if registriesTOML != nil {
tmpFile, err = os.CreateTemp("", "regtemp")
if err != nil {
return nil, err
}
defer func() {
tmpFile.Close()
os.Remove(tmpFile.Name())
}()

_, err = tmpFile.Write(registriesTOML)
if err != nil {
return nil, err
}

if _, err := toml.NewDecoder(bytes.NewBuffer(registriesTOML)).Decode(&registriesConf); err != nil {
return nil, fmt.Errorf("error decoding registries config: %w", err)
}
}
for scope := range clusterScopePolicies {
registriesDockerConfig[scope] = sigstoreAttachment

for policyScope := range clusterScopePolicies {
registriesDockerConfig[policyScope] = sigstoreAttachment
if registriesTOML == nil {
continue
}
parentReg, err := sysregistriesv2.FindRegistry(&types.SystemContext{SystemRegistriesConfPath: tmpFile.Name(), SystemRegistriesConfDirPath: os.DevNull}, policyScope)
if err != nil {
return nil, err
}

if err = addScopeMirrorsSigstoreRegistriesdConfig(registriesDockerConfig, policyScope, parentReg, sigstoreAttachment); err != nil {
return nil, fmt.Errorf("error adding clusterimagepolicy scope %s relevant mirrors: %w", policyScope, err)
}
for _, reg := range registriesConf.Registries {
scope := reg.Location
if reg.Prefix != "" {
scope = reg.Prefix
}
if runtimeutils.ScopeIsNestedInsideScope(scope, policyScope) && scope != policyScope {
nestedReg, err := sysregistriesv2.FindRegistry(&types.SystemContext{SystemRegistriesConfPath: tmpFile.Name()}, scope)
if err != nil {
return nil, err
}
if err = addScopeMirrorsSigstoreRegistriesdConfig(registriesDockerConfig, scope, nestedReg, sigstoreAttachment); err != nil {
return nil, fmt.Errorf("error adding clusterimagepolicy scope %s relevant mirrors: %w", policyScope, err)
}
}
}
}

registriesConfig := &registriesConfig{}
Expand All @@ -954,3 +1007,65 @@ func generateSigstoreRegistriesdConfig(clusterScopePolicies map[string]signature
}
return data, nil
}

func addScopeMirrorsSigstoreRegistriesdConfig(registriesDockerConfig map[string]dockerConfig, scope string, reg *sysregistriesv2.Registry, sigstoreAttachment dockerConfig) error {
if reg == nil {
return nil
}
dummyDigest := "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
dummyTag := "aaa"
dummyPath := "/a"
dummyPrefix := "matched"
addedDummy := false
hasWildcard := false
originalScope := scope

if strings.HasPrefix(scope, "*.") {
scope = strings.Replace(scope, "*", dummyPrefix, 1)
hasWildcard = true
}

if !strings.Contains(scope, "/") {
scope += dummyPath
addedDummy = true
}

scopeRef, err := reference.Parse(scope)
if err != nil {
return fmt.Errorf("error parsing scope %s: %w", scope, err)
}

repo := reference.TrimNamed(scopeRef.(reference.Named))

d, _ := digest.Parse(dummyDigest)
digestRef, err := reference.WithDigest(repo, d)
if err != nil {
return fmt.Errorf("error parsing digest name for scope %s: %w", scope, err)
}
tagRef, err := reference.WithTag(repo, dummyTag)
if err != nil {
return fmt.Errorf("error parsing tag name for scope %s: %w", scope, err)
}

digestSources, err := reg.PullSourcesFromReference(digestRef)
if err != nil {
return fmt.Errorf("error getting digest sources for scope %s: %w", scope, err)
}
tagSources, err := reg.PullSourcesFromReference(tagRef)
if err != nil {
return fmt.Errorf("error getting tag sources for scope %s: %w", scope, err)
}
for _, s := range append(digestSources, tagSources...) {
endpoint := s.Reference.Name()
if addedDummy {
endpoint = strings.TrimSuffix(endpoint, dummyPath)
}
if hasWildcard {
if endpoint == strings.Replace(originalScope, "*", dummyPrefix, 1) {
continue
}
}
registriesDockerConfig[endpoint] = sigstoreAttachment
}
return nil
}
Loading

0 comments on commit 78f043b

Please sign in to comment.