Skip to content

Commit

Permalink
fix: use the docker credentials from the specified dockerConfigJsonSe…
Browse files Browse the repository at this point in the history
…cretName when checking if the image exists
  • Loading branch information
yetone committed Jan 17, 2023
1 parent 8eea644 commit ea82e2b
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 15 deletions.
6 changes: 5 additions & 1 deletion apis/resources/v1alpha1/bentorequest_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ type BentoRequestSpec struct {
Models []BentoModel `json:"models,omitempty"`

// +kubebuilder:validation:Optional
Image *string `json:"image,omitempty"`
Image string `json:"image,omitempty"`

ImageBuildTimeout *time.Duration `json:"imageBuildTimeout,omitempty"`

Expand All @@ -75,6 +75,9 @@ type BentoRequestSpec struct {
// +kubebuilder:validation:Optional
DockerConfigJSONSecretName string `json:"dockerConfigJsonSecretName,omitempty"`

// +kubebuilder:validation:Optional
OCIRegistryInsecure *bool `json:"ociRegistryInsecure,omitempty"`

// +kubebuilder:validation:Optional
DownloaderContainerEnvFrom []corev1.EnvFromSource `json:"downloaderContainerEnvFrom,omitempty"`
}
Expand All @@ -92,6 +95,7 @@ type BentoRequestStatus struct {
//+kubebuilder:subresource:status
//+kubebuilder:printcolumn:name="Bento-Tag",type="string",JSONPath=".spec.bentoTag",description="Bento Tag"
//+kubebuilder:printcolumn:name="Download-Url",type="string",JSONPath=".spec.downloadUrl",description="Download URL"
//+kubebuilder:printcolumn:name="Image",type="string",JSONPath=".spec.image",description="Image"
//+kubebuilder:printcolumn:name="Image-Exists",type="string",JSONPath=".status.conditions[?(@.type=='ImageExists')].status",description="Image Exists"
//+kubebuilder:printcolumn:name="Bento-Available",type="string",JSONPath=".status.conditions[?(@.type=='BentoAvailable')].status",description="Bento Available"
//+kubebuilder:printcolumn:name="Image-Builder-Pod-Phase",type="string",JSONPath=".status.imageBuilderPodStatus.phase",description="Image Builder Pod Phase"
Expand Down
10 changes: 5 additions & 5 deletions apis/resources/v1alpha1/zz_generated.deepcopy.go

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

6 changes: 6 additions & 0 deletions config/crd/bases/resources.yatai.ai_bentorequests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ spec:
jsonPath: .spec.downloadUrl
name: Download-Url
type: string
- description: Image
jsonPath: .spec.image
name: Image
type: string
- description: Image Exists
jsonPath: .status.conditions[?(@.type=='ImageExists')].status
name: Image-Exists
Expand Down Expand Up @@ -1360,6 +1364,8 @@ spec:
- tag
type: object
type: array
ociRegistryInsecure:
type: boolean
runners:
items:
properties:
Expand Down
79 changes: 75 additions & 4 deletions controllers/resources/bentorequest_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,75 @@ func getYataiClient(ctx context.Context) (yataiClient **yataiclient.YataiClient,
return
}

func getDockerRegistry(ctx context.Context, cliset *kubernetes.Clientset) (dockerRegistry modelschemas.DockerRegistrySchema, err error) {
func getDockerRegistry(ctx context.Context, bentoRequest *resourcesv1alpha1.BentoRequest, cliset *kubernetes.Clientset) (dockerRegistry modelschemas.DockerRegistrySchema, err error) {
if bentoRequest != nil && bentoRequest.Spec.DockerConfigJSONSecretName != "" {
var secret *corev1.Secret
secret, err = cliset.CoreV1().Secrets(bentoRequest.Namespace).Get(ctx, bentoRequest.Spec.DockerConfigJSONSecretName, metav1.GetOptions{})
if err != nil {
err = errors.Wrapf(err, "get docker config json secret %s", bentoRequest.Spec.DockerConfigJSONSecretName)
return
}
configJSON, ok := secret.Data[".dockerconfigjson"]
if !ok {
err = errors.Errorf("docker config json secret %s does not have .dockerconfigjson key", bentoRequest.Spec.DockerConfigJSONSecretName)
return
}
var configObj struct {
Auths map[string]struct {
Auth string `json:"auth"`
} `json:"auths"`
}
err = json.Unmarshal(configJSON, &configObj)
if err != nil {
err = errors.Wrapf(err, "unmarshal docker config json secret %s", bentoRequest.Spec.DockerConfigJSONSecretName)
return
}
imageRegistryURI, _, _ := xstrings.Partition(bentoRequest.Spec.Image, "/")
var server string
var auth string
if imageRegistryURI != "" {
for k, v := range configObj.Auths {
if k == imageRegistryURI {
server = k
auth = v.Auth
break
}
}
if server == "" {
for k, v := range configObj.Auths {
if strings.Contains(k, imageRegistryURI) {
server = k
auth = v.Auth
break
}
}
}
}
if server == "" {
for k, v := range configObj.Auths {
server = k
auth = v.Auth
break
}
}
if server == "" {
err = errors.Errorf("no auth in docker config json secret %s", bentoRequest.Spec.DockerConfigJSONSecretName)
return
}
dockerRegistry.Server = server
var credentials []byte
credentials, err = base64.StdEncoding.DecodeString(auth)
if err != nil {
err = errors.Wrapf(err, "cannot base64 decode auth in docker config json secret %s", bentoRequest.Spec.DockerConfigJSONSecretName)
return
}
dockerRegistry.Username, _, dockerRegistry.Password = xstrings.Partition(string(credentials), ":")
if bentoRequest.Spec.OCIRegistryInsecure != nil {
dockerRegistry.Secure = !*bentoRequest.Spec.OCIRegistryInsecure
}
return
}

dockerRegistryConfig, err := commonconfig.GetDockerRegistryConfig(ctx, cliset)
if err != nil {
err = errors.Wrap(err, "get docker registry")
Expand Down Expand Up @@ -820,8 +888,8 @@ func getDockerRegistry(ctx context.Context, cliset *kubernetes.Clientset) (docke
}

func getBentoImageName(bentoRequest *resourcesv1alpha1.BentoRequest, dockerRegistry modelschemas.DockerRegistrySchema, bentoRepositoryName, bentoVersion string, inCluster bool) string {
if bentoRequest != nil && bentoRequest.Spec.Image != nil && *bentoRequest.Spec.Image != "" {
return *bentoRequest.Spec.Image
if bentoRequest != nil && bentoRequest.Spec.Image != "" {
return bentoRequest.Spec.Image
}
var imageName string
if inCluster {
Expand Down Expand Up @@ -889,7 +957,7 @@ func (r *BentoRequestReconciler) getImageInfo(ctx context.Context, opt GetImageI
err = errors.Wrap(err, "create kubernetes clientset")
return
}
dockerRegistry, err := getDockerRegistry(ctx, kubeCli)
dockerRegistry, err := getDockerRegistry(ctx, opt.BentoRequest, kubeCli)
if err != nil {
err = errors.Wrap(err, "get docker registry")
return
Expand All @@ -901,6 +969,9 @@ func (r *BentoRequestReconciler) getImageInfo(ctx context.Context, opt GetImageI
imageInfo.DockerConfigJSONSecretName = opt.BentoRequest.Spec.DockerConfigJSONSecretName

imageInfo.DockerRegistryInsecure = opt.BentoRequest.Annotations[commonconsts.KubeAnnotationDockerRegistryInsecure] == "true"
if opt.BentoRequest.Spec.OCIRegistryInsecure != nil {
imageInfo.DockerRegistryInsecure = *opt.BentoRequest.Spec.OCIRegistryInsecure
}

if imageInfo.DockerConfigJSONSecretName == "" {
var dockerRegistryConf *commonconfig.DockerRegistryConfig
Expand Down
6 changes: 6 additions & 0 deletions helm/yatai-image-builder-crds/templates/bentorequest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ spec:
jsonPath: .spec.downloadUrl
name: Download-Url
type: string
- description: Image
jsonPath: .spec.image
name: Image
type: string
- description: Image Exists
jsonPath: .status.conditions[?(@.type=='ImageExists')].status
name: Image-Exists
Expand Down Expand Up @@ -898,6 +902,8 @@ spec:
- tag
type: object
type: array
ociRegistryInsecure:
type: boolean
runners:
items:
properties:
Expand Down
25 changes: 20 additions & 5 deletions tests/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ var _ = Describe("yatai-image-builder", Ordered, func() {
if err != nil {
return err
}
if len(pods.Items) != 1 {
return fmt.Errorf("expected 1 pod, got %d", len(pods.Items))
if len(pods.Items) != 2 {
return fmt.Errorf("expected 2 pod, got %d", len(pods.Items))
}
pod := pods.Items[0]
if pod.Status.Phase == corev1.PodFailed {
Expand All @@ -98,16 +98,31 @@ var _ = Describe("yatai-image-builder", Ordered, func() {

logrus.Infof("Getting BentoRequest CR %s", "test-bento")
bentoRequest, err := bentorequestcli.BentoRequests("yatai").Get(ctx, "test-bento", metav1.GetOptions{})
Expect(err).To(BeNil(), "failed to get BentoRequest CR")
Expect(err).To(BeNil(), "failed to get BentoRequest CR test-bento")

logrus.Infof("Getting Bento CR %s", "test-bento")
bento, err := bentorequestcli.Bentoes("yatai").Get(ctx, "test-bento", metav1.GetOptions{})
if err != nil {
return err
}

Expect(bentoRequest.Spec.BentoTag).To(Equal(bento.Spec.Tag), "BentoRequest and Bento tag should match")
Expect(bento.Spec.Image).To(Not(BeEmpty()), "Bento CR image should not be empty")
Expect(bentoRequest.Spec.BentoTag).To(Equal(bento.Spec.Tag), "bentoRequest and bento tag should match")
Expect(bento.Spec.Image).To(Not(BeEmpty()), "bento CR image should not be empty")

logrus.Infof("Getting BentoRequest CR %s", "test-bento1")

bentoRequest1, err := bentorequestcli.BentoRequests("yatai").Get(ctx, "test-bento1", metav1.GetOptions{})
Expect(err).To(BeNil(), "failed to get BentoRequest CR test-bento1")

logrus.Infof("Getting Bento CR %s", "test-bento1")
bento1, err := bentorequestcli.Bentoes("yatai").Get(ctx, "test-bento1", metav1.GetOptions{})
if err != nil {
return err
}

Expect(bentoRequest1.Spec.BentoTag).To(Equal(bento1.Spec.Tag), "bentoRequest1 and bento1 tag should match")
Expect(bento1.Spec.Image).To(Not(BeEmpty()), "bento1 CR image should not be empty")
Expect(bentoRequest1.Spec.Image).To(Equal(bento1.Spec.Image), "bentoRequest1 and bento1 image should match")
return nil
}, time.Minute, time.Second).Should(Succeed())
})
Expand Down
12 changes: 12 additions & 0 deletions tests/e2e/example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,15 @@ metadata:
spec:
bentoTag: iris_classifier:r4zint4b567i4usu234
downloadUrl: s3://yetone/bentos/test-bento.bento
---
apiVersion: resources.yatai.ai/v1alpha1
kind: BentoRequest
metadata:
name: test-bento1
namespace: yatai
spec:
image: docker-registry-1.yatai-image-builder.svc.cluster.local:5000/test-custom-image:v1
ociRegistryInsecure: true
dockerConfigJsonSecretName: regcred
bentoTag: iris_classifier:r4zint4b567i4usu234
downloadUrl: s3://yetone/bentos/test-bento.bento
18 changes: 18 additions & 0 deletions tests/e2e/installation_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,21 @@ YATAI_ENDPOINT='empty' USE_LOCAL_HELM_CHART=true UPGRADE_CRDS=false AWS_SECRET_A
echo "yatai-image-builder helm release values:"
helm get values yatai-image-builder -n yatai-image-builder

helm upgrade --install docker-registry-1 twuni/docker-registry -n yatai-image-builder --set secrets.htpasswd='yetone:$2y$05$L7dlu/IGePjzo7C4YbmivOJxHs4jZ9k08D3CAAhxRQJoF62ey93yq'
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: yatai
stringData:
.dockerconfigjson: |
{
"auths": {
"docker-registry-1.yatai-image-builder.svc.cluster.local:5000": {
"auth": "$(echo -n 'yetone:password' | base64)"
}
}
}
type: kubernetes.io/dockerconfigjson
EOF

0 comments on commit ea82e2b

Please sign in to comment.