|
@@ -2,6 +2,7 @@ package kubernetes
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"bufio"
|
|
"bufio"
|
|
|
|
|
+ "bytes"
|
|
|
"context"
|
|
"context"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"io"
|
|
"io"
|
|
@@ -11,10 +12,17 @@ import (
|
|
|
"github.com/porter-dev/porter/internal/kubernetes/provisioner/aws"
|
|
"github.com/porter-dev/porter/internal/kubernetes/provisioner/aws"
|
|
|
"github.com/porter-dev/porter/internal/kubernetes/provisioner/aws/ecr"
|
|
"github.com/porter-dev/porter/internal/kubernetes/provisioner/aws/ecr"
|
|
|
"github.com/porter-dev/porter/internal/kubernetes/provisioner/aws/eks"
|
|
"github.com/porter-dev/porter/internal/kubernetes/provisioner/aws/eks"
|
|
|
|
|
+ "github.com/porter-dev/porter/internal/kubernetes/provisioner/do"
|
|
|
|
|
+ "github.com/porter-dev/porter/internal/kubernetes/provisioner/do/docr"
|
|
|
|
|
+ "github.com/porter-dev/porter/internal/kubernetes/provisioner/do/doks"
|
|
|
"github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp"
|
|
"github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp"
|
|
|
"github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp/gke"
|
|
"github.com/porter-dev/porter/internal/kubernetes/provisioner/gcp/gke"
|
|
|
"github.com/porter-dev/porter/internal/models"
|
|
"github.com/porter-dev/porter/internal/models"
|
|
|
"github.com/porter-dev/porter/internal/models/integrations"
|
|
"github.com/porter-dev/porter/internal/models/integrations"
|
|
|
|
|
+ "github.com/porter-dev/porter/internal/oauth"
|
|
|
|
|
+ "github.com/porter-dev/porter/internal/registry"
|
|
|
|
|
+ "github.com/porter-dev/porter/internal/repository"
|
|
|
|
|
+ "golang.org/x/oauth2"
|
|
|
|
|
|
|
|
"github.com/gorilla/websocket"
|
|
"github.com/gorilla/websocket"
|
|
|
"github.com/porter-dev/porter/internal/helm/grapher"
|
|
"github.com/porter-dev/porter/internal/helm/grapher"
|
|
@@ -22,6 +30,7 @@ import (
|
|
|
batchv1 "k8s.io/api/batch/v1"
|
|
batchv1 "k8s.io/api/batch/v1"
|
|
|
v1 "k8s.io/api/core/v1"
|
|
v1 "k8s.io/api/core/v1"
|
|
|
v1beta1 "k8s.io/api/extensions/v1beta1"
|
|
v1beta1 "k8s.io/api/extensions/v1beta1"
|
|
|
|
|
+ "k8s.io/apimachinery/pkg/api/errors"
|
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
|
|
"k8s.io/client-go/informers"
|
|
"k8s.io/client-go/informers"
|
|
@@ -114,8 +123,9 @@ func (a *Agent) GetPodsByLabel(selector string) (*v1.PodList, error) {
|
|
|
|
|
|
|
|
// GetPodLogs streams real-time logs from a given pod.
|
|
// GetPodLogs streams real-time logs from a given pod.
|
|
|
func (a *Agent) GetPodLogs(namespace string, name string, conn *websocket.Conn) error {
|
|
func (a *Agent) GetPodLogs(namespace string, name string, conn *websocket.Conn) error {
|
|
|
|
|
+ tails := int64(400)
|
|
|
|
|
+
|
|
|
// follow logs
|
|
// follow logs
|
|
|
- tails := int64(30)
|
|
|
|
|
podLogOpts := v1.PodLogOptions{
|
|
podLogOpts := v1.PodLogOptions{
|
|
|
Follow: true,
|
|
Follow: true,
|
|
|
TailLines: &tails,
|
|
TailLines: &tails,
|
|
@@ -150,6 +160,7 @@ func (a *Agent) GetPodLogs(namespace string, name string, conn *websocket.Conn)
|
|
|
return
|
|
return
|
|
|
default:
|
|
default:
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
bytes, err := r.ReadBytes('\n')
|
|
bytes, err := r.ReadBytes('\n')
|
|
|
if writeErr := conn.WriteMessage(websocket.TextMessage, bytes); writeErr != nil {
|
|
if writeErr := conn.WriteMessage(websocket.TextMessage, bytes); writeErr != nil {
|
|
|
errorchan <- writeErr
|
|
errorchan <- writeErr
|
|
@@ -241,13 +252,14 @@ func (a *Agent) ProvisionECR(
|
|
|
projectID uint,
|
|
projectID uint,
|
|
|
awsConf *integrations.AWSIntegration,
|
|
awsConf *integrations.AWSIntegration,
|
|
|
ecrName string,
|
|
ecrName string,
|
|
|
|
|
+ repo repository.Repository,
|
|
|
infra *models.Infra,
|
|
infra *models.Infra,
|
|
|
operation provisioner.ProvisionerOperation,
|
|
operation provisioner.ProvisionerOperation,
|
|
|
pgConf *config.DBConf,
|
|
pgConf *config.DBConf,
|
|
|
redisConf *config.RedisConf,
|
|
redisConf *config.RedisConf,
|
|
|
provImageTag string,
|
|
provImageTag string,
|
|
|
) (*batchv1.Job, error) {
|
|
) (*batchv1.Job, error) {
|
|
|
- id := infra.GetID()
|
|
|
|
|
|
|
+ id := infra.GetUniqueName()
|
|
|
prov := &provisioner.Conf{
|
|
prov := &provisioner.Conf{
|
|
|
ID: id,
|
|
ID: id,
|
|
|
Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
@@ -256,6 +268,7 @@ func (a *Agent) ProvisionECR(
|
|
|
Redis: redisConf,
|
|
Redis: redisConf,
|
|
|
Postgres: pgConf,
|
|
Postgres: pgConf,
|
|
|
ProvisionerImageTag: provImageTag,
|
|
ProvisionerImageTag: provImageTag,
|
|
|
|
|
+ LastApplied: infra.LastApplied,
|
|
|
AWS: &aws.Conf{
|
|
AWS: &aws.Conf{
|
|
|
AWSRegion: awsConf.AWSRegion,
|
|
AWSRegion: awsConf.AWSRegion,
|
|
|
AWSAccessKeyID: string(awsConf.AWSAccessKeyID),
|
|
AWSAccessKeyID: string(awsConf.AWSAccessKeyID),
|
|
@@ -266,7 +279,7 @@ func (a *Agent) ProvisionECR(
|
|
|
},
|
|
},
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return a.provision(prov)
|
|
|
|
|
|
|
+ return a.provision(prov, infra, repo)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ProvisionEKS spawns a new provisioning pod that creates an EKS instance
|
|
// ProvisionEKS spawns a new provisioning pod that creates an EKS instance
|
|
@@ -274,13 +287,14 @@ func (a *Agent) ProvisionEKS(
|
|
|
projectID uint,
|
|
projectID uint,
|
|
|
awsConf *integrations.AWSIntegration,
|
|
awsConf *integrations.AWSIntegration,
|
|
|
eksName string,
|
|
eksName string,
|
|
|
|
|
+ repo repository.Repository,
|
|
|
infra *models.Infra,
|
|
infra *models.Infra,
|
|
|
operation provisioner.ProvisionerOperation,
|
|
operation provisioner.ProvisionerOperation,
|
|
|
pgConf *config.DBConf,
|
|
pgConf *config.DBConf,
|
|
|
redisConf *config.RedisConf,
|
|
redisConf *config.RedisConf,
|
|
|
provImageTag string,
|
|
provImageTag string,
|
|
|
) (*batchv1.Job, error) {
|
|
) (*batchv1.Job, error) {
|
|
|
- id := infra.GetID()
|
|
|
|
|
|
|
+ id := infra.GetUniqueName()
|
|
|
prov := &provisioner.Conf{
|
|
prov := &provisioner.Conf{
|
|
|
ID: id,
|
|
ID: id,
|
|
|
Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
@@ -289,6 +303,7 @@ func (a *Agent) ProvisionEKS(
|
|
|
Redis: redisConf,
|
|
Redis: redisConf,
|
|
|
Postgres: pgConf,
|
|
Postgres: pgConf,
|
|
|
ProvisionerImageTag: provImageTag,
|
|
ProvisionerImageTag: provImageTag,
|
|
|
|
|
+ LastApplied: infra.LastApplied,
|
|
|
AWS: &aws.Conf{
|
|
AWS: &aws.Conf{
|
|
|
AWSRegion: awsConf.AWSRegion,
|
|
AWSRegion: awsConf.AWSRegion,
|
|
|
AWSAccessKeyID: string(awsConf.AWSAccessKeyID),
|
|
AWSAccessKeyID: string(awsConf.AWSAccessKeyID),
|
|
@@ -299,20 +314,21 @@ func (a *Agent) ProvisionEKS(
|
|
|
},
|
|
},
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return a.provision(prov)
|
|
|
|
|
|
|
+ return a.provision(prov, infra, repo)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ProvisionGCR spawns a new provisioning pod that creates a GCR instance
|
|
// ProvisionGCR spawns a new provisioning pod that creates a GCR instance
|
|
|
func (a *Agent) ProvisionGCR(
|
|
func (a *Agent) ProvisionGCR(
|
|
|
projectID uint,
|
|
projectID uint,
|
|
|
gcpConf *integrations.GCPIntegration,
|
|
gcpConf *integrations.GCPIntegration,
|
|
|
|
|
+ repo repository.Repository,
|
|
|
infra *models.Infra,
|
|
infra *models.Infra,
|
|
|
operation provisioner.ProvisionerOperation,
|
|
operation provisioner.ProvisionerOperation,
|
|
|
pgConf *config.DBConf,
|
|
pgConf *config.DBConf,
|
|
|
redisConf *config.RedisConf,
|
|
redisConf *config.RedisConf,
|
|
|
provImageTag string,
|
|
provImageTag string,
|
|
|
) (*batchv1.Job, error) {
|
|
) (*batchv1.Job, error) {
|
|
|
- id := infra.GetID()
|
|
|
|
|
|
|
+ id := infra.GetUniqueName()
|
|
|
prov := &provisioner.Conf{
|
|
prov := &provisioner.Conf{
|
|
|
ID: id,
|
|
ID: id,
|
|
|
Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
@@ -321,6 +337,7 @@ func (a *Agent) ProvisionGCR(
|
|
|
Redis: redisConf,
|
|
Redis: redisConf,
|
|
|
Postgres: pgConf,
|
|
Postgres: pgConf,
|
|
|
ProvisionerImageTag: provImageTag,
|
|
ProvisionerImageTag: provImageTag,
|
|
|
|
|
+ LastApplied: infra.LastApplied,
|
|
|
GCP: &gcp.Conf{
|
|
GCP: &gcp.Conf{
|
|
|
GCPRegion: gcpConf.GCPRegion,
|
|
GCPRegion: gcpConf.GCPRegion,
|
|
|
GCPProjectID: gcpConf.GCPProjectID,
|
|
GCPProjectID: gcpConf.GCPProjectID,
|
|
@@ -328,7 +345,7 @@ func (a *Agent) ProvisionGCR(
|
|
|
},
|
|
},
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return a.provision(prov)
|
|
|
|
|
|
|
+ return a.provision(prov, infra, repo)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ProvisionGKE spawns a new provisioning pod that creates a GKE instance
|
|
// ProvisionGKE spawns a new provisioning pod that creates a GKE instance
|
|
@@ -336,13 +353,14 @@ func (a *Agent) ProvisionGKE(
|
|
|
projectID uint,
|
|
projectID uint,
|
|
|
gcpConf *integrations.GCPIntegration,
|
|
gcpConf *integrations.GCPIntegration,
|
|
|
gkeName string,
|
|
gkeName string,
|
|
|
|
|
+ repo repository.Repository,
|
|
|
infra *models.Infra,
|
|
infra *models.Infra,
|
|
|
operation provisioner.ProvisionerOperation,
|
|
operation provisioner.ProvisionerOperation,
|
|
|
pgConf *config.DBConf,
|
|
pgConf *config.DBConf,
|
|
|
redisConf *config.RedisConf,
|
|
redisConf *config.RedisConf,
|
|
|
provImageTag string,
|
|
provImageTag string,
|
|
|
) (*batchv1.Job, error) {
|
|
) (*batchv1.Job, error) {
|
|
|
- id := infra.GetID()
|
|
|
|
|
|
|
+ id := infra.GetUniqueName()
|
|
|
prov := &provisioner.Conf{
|
|
prov := &provisioner.Conf{
|
|
|
ID: id,
|
|
ID: id,
|
|
|
Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
@@ -351,6 +369,7 @@ func (a *Agent) ProvisionGKE(
|
|
|
Redis: redisConf,
|
|
Redis: redisConf,
|
|
|
Postgres: pgConf,
|
|
Postgres: pgConf,
|
|
|
ProvisionerImageTag: provImageTag,
|
|
ProvisionerImageTag: provImageTag,
|
|
|
|
|
+ LastApplied: infra.LastApplied,
|
|
|
GCP: &gcp.Conf{
|
|
GCP: &gcp.Conf{
|
|
|
GCPRegion: gcpConf.GCPRegion,
|
|
GCPRegion: gcpConf.GCPRegion,
|
|
|
GCPProjectID: gcpConf.GCPProjectID,
|
|
GCPProjectID: gcpConf.GCPProjectID,
|
|
@@ -361,20 +380,124 @@ func (a *Agent) ProvisionGKE(
|
|
|
},
|
|
},
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return a.provision(prov)
|
|
|
|
|
|
|
+ return a.provision(prov, infra, repo)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ProvisionDOCR spawns a new provisioning pod that creates a DOCR instance
|
|
|
|
|
+func (a *Agent) ProvisionDOCR(
|
|
|
|
|
+ projectID uint,
|
|
|
|
|
+ doConf *integrations.OAuthIntegration,
|
|
|
|
|
+ doAuth *oauth2.Config,
|
|
|
|
|
+ repo repository.Repository,
|
|
|
|
|
+ docrName, docrSubscriptionTier string,
|
|
|
|
|
+ infra *models.Infra,
|
|
|
|
|
+ operation provisioner.ProvisionerOperation,
|
|
|
|
|
+ pgConf *config.DBConf,
|
|
|
|
|
+ redisConf *config.RedisConf,
|
|
|
|
|
+ provImageTag string,
|
|
|
|
|
+) (*batchv1.Job, error) {
|
|
|
|
|
+ // get the token
|
|
|
|
|
+ oauthInt, err := repo.OAuthIntegration.ReadOAuthIntegration(
|
|
|
|
|
+ infra.DOIntegrationID,
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tok, _, err := oauth.GetAccessToken(oauthInt, doAuth, repo)
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ id := infra.GetUniqueName()
|
|
|
|
|
+ prov := &provisioner.Conf{
|
|
|
|
|
+ ID: id,
|
|
|
|
|
+ Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
|
|
|
+ Kind: provisioner.DOCR,
|
|
|
|
|
+ Operation: operation,
|
|
|
|
|
+ Redis: redisConf,
|
|
|
|
|
+ Postgres: pgConf,
|
|
|
|
|
+ ProvisionerImageTag: provImageTag,
|
|
|
|
|
+ LastApplied: infra.LastApplied,
|
|
|
|
|
+ DO: &do.Conf{
|
|
|
|
|
+ DOToken: tok,
|
|
|
|
|
+ },
|
|
|
|
|
+ DOCR: &docr.Conf{
|
|
|
|
|
+ DOCRName: docrName,
|
|
|
|
|
+ DOCRSubscriptionTier: docrSubscriptionTier,
|
|
|
|
|
+ },
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return a.provision(prov, infra, repo)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// ProvisionDOKS spawns a new provisioning pod that creates a DOKS instance
|
|
|
|
|
+func (a *Agent) ProvisionDOKS(
|
|
|
|
|
+ projectID uint,
|
|
|
|
|
+ doConf *integrations.OAuthIntegration,
|
|
|
|
|
+ doAuth *oauth2.Config,
|
|
|
|
|
+ repo repository.Repository,
|
|
|
|
|
+ doRegion, doksClusterName string,
|
|
|
|
|
+ infra *models.Infra,
|
|
|
|
|
+ operation provisioner.ProvisionerOperation,
|
|
|
|
|
+ pgConf *config.DBConf,
|
|
|
|
|
+ redisConf *config.RedisConf,
|
|
|
|
|
+ provImageTag string,
|
|
|
|
|
+) (*batchv1.Job, error) {
|
|
|
|
|
+ // get the token
|
|
|
|
|
+ oauthInt, err := repo.OAuthIntegration.ReadOAuthIntegration(
|
|
|
|
|
+ infra.DOIntegrationID,
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tok, _, err := oauth.GetAccessToken(oauthInt, doAuth, repo)
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ id := infra.GetUniqueName()
|
|
|
|
|
+ prov := &provisioner.Conf{
|
|
|
|
|
+ ID: id,
|
|
|
|
|
+ Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
|
|
|
+ Kind: provisioner.DOKS,
|
|
|
|
|
+ Operation: operation,
|
|
|
|
|
+ Redis: redisConf,
|
|
|
|
|
+ Postgres: pgConf,
|
|
|
|
|
+ LastApplied: infra.LastApplied,
|
|
|
|
|
+ ProvisionerImageTag: provImageTag,
|
|
|
|
|
+ DO: &do.Conf{
|
|
|
|
|
+ DOToken: tok,
|
|
|
|
|
+ },
|
|
|
|
|
+ DOKS: &doks.Conf{
|
|
|
|
|
+ DORegion: doRegion,
|
|
|
|
|
+ DOKSClusterName: doksClusterName,
|
|
|
|
|
+ },
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return a.provision(prov, infra, repo)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ProvisionTest spawns a new provisioning pod that tests provisioning
|
|
// ProvisionTest spawns a new provisioning pod that tests provisioning
|
|
|
func (a *Agent) ProvisionTest(
|
|
func (a *Agent) ProvisionTest(
|
|
|
projectID uint,
|
|
projectID uint,
|
|
|
|
|
+ infra *models.Infra,
|
|
|
|
|
+ repo repository.Repository,
|
|
|
operation provisioner.ProvisionerOperation,
|
|
operation provisioner.ProvisionerOperation,
|
|
|
pgConf *config.DBConf,
|
|
pgConf *config.DBConf,
|
|
|
redisConf *config.RedisConf,
|
|
redisConf *config.RedisConf,
|
|
|
provImageTag string,
|
|
provImageTag string,
|
|
|
) (*batchv1.Job, error) {
|
|
) (*batchv1.Job, error) {
|
|
|
|
|
+ id := infra.GetUniqueName()
|
|
|
|
|
+
|
|
|
prov := &provisioner.Conf{
|
|
prov := &provisioner.Conf{
|
|
|
- ID: fmt.Sprintf("%s-%d", "testing", projectID),
|
|
|
|
|
- Name: fmt.Sprintf("prov-%s-%d-%s", "testing", projectID, string(operation)),
|
|
|
|
|
|
|
+ ID: id,
|
|
|
|
|
+ Name: fmt.Sprintf("prov-%s-%s", id, string(operation)),
|
|
|
Operation: operation,
|
|
Operation: operation,
|
|
|
Kind: provisioner.Test,
|
|
Kind: provisioner.Test,
|
|
|
Redis: redisConf,
|
|
Redis: redisConf,
|
|
@@ -382,11 +505,13 @@ func (a *Agent) ProvisionTest(
|
|
|
ProvisionerImageTag: provImageTag,
|
|
ProvisionerImageTag: provImageTag,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return a.provision(prov)
|
|
|
|
|
|
|
+ return a.provision(prov, infra, repo)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func (a *Agent) provision(
|
|
func (a *Agent) provision(
|
|
|
prov *provisioner.Conf,
|
|
prov *provisioner.Conf,
|
|
|
|
|
+ infra *models.Infra,
|
|
|
|
|
+ repo repository.Repository,
|
|
|
) (*batchv1.Job, error) {
|
|
) (*batchv1.Job, error) {
|
|
|
prov.Namespace = "default"
|
|
prov.Namespace = "default"
|
|
|
|
|
|
|
@@ -396,9 +521,106 @@ func (a *Agent) provision(
|
|
|
return nil, err
|
|
return nil, err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return a.Clientset.BatchV1().Jobs(prov.Namespace).Create(
|
|
|
|
|
|
|
+ job, err = a.Clientset.BatchV1().Jobs(prov.Namespace).Create(
|
|
|
context.TODO(),
|
|
context.TODO(),
|
|
|
job,
|
|
job,
|
|
|
metav1.CreateOptions{},
|
|
metav1.CreateOptions{},
|
|
|
)
|
|
)
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ infra.LastApplied = prov.LastApplied
|
|
|
|
|
+ infra, err = repo.Infra.UpdateInfra(infra)
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return job, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// CreateImagePullSecrets will create the required image pull secrets and
|
|
|
|
|
+// return a map from the registry name to the name of the secret.
|
|
|
|
|
+func (a *Agent) CreateImagePullSecrets(
|
|
|
|
|
+ repo repository.Repository,
|
|
|
|
|
+ namespace string,
|
|
|
|
|
+ linkedRegs map[string]*models.Registry,
|
|
|
|
|
+ doAuth *oauth2.Config,
|
|
|
|
|
+) (map[string]string, error) {
|
|
|
|
|
+ res := make(map[string]string)
|
|
|
|
|
+
|
|
|
|
|
+ for key, val := range linkedRegs {
|
|
|
|
|
+ _reg := registry.Registry(*val)
|
|
|
|
|
+
|
|
|
|
|
+ data, err := _reg.GetDockerConfigJSON(repo, doAuth)
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ secretName := fmt.Sprintf("porter-%s-%d", val.Externalize().Service, val.ID)
|
|
|
|
|
+
|
|
|
|
|
+ secret, err := a.Clientset.CoreV1().Secrets(namespace).Get(
|
|
|
|
|
+ context.TODO(),
|
|
|
|
|
+ secretName,
|
|
|
|
|
+ metav1.GetOptions{},
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ // if not found, create the secret
|
|
|
|
|
+ if err != nil && errors.IsNotFound(err) {
|
|
|
|
|
+ _, err = a.Clientset.CoreV1().Secrets(namespace).Create(
|
|
|
|
|
+ context.TODO(),
|
|
|
|
|
+ &v1.Secret{
|
|
|
|
|
+ ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
+ Name: secretName,
|
|
|
|
|
+ },
|
|
|
|
|
+ Data: map[string][]byte{
|
|
|
|
|
+ string(v1.DockerConfigJsonKey): data,
|
|
|
|
|
+ },
|
|
|
|
|
+ Type: v1.SecretTypeDockerConfigJson,
|
|
|
|
|
+ },
|
|
|
|
|
+ metav1.CreateOptions{},
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // add secret name to the map
|
|
|
|
|
+ res[key] = secretName
|
|
|
|
|
+
|
|
|
|
|
+ continue
|
|
|
|
|
+ } else if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // otherwise, check that the secret contains the correct data: if
|
|
|
|
|
+ // if doesn't, update it
|
|
|
|
|
+ if !bytes.Equal(secret.Data[v1.DockerConfigJsonKey], data) {
|
|
|
|
|
+ _, err := a.Clientset.CoreV1().Secrets(namespace).Update(
|
|
|
|
|
+ context.TODO(),
|
|
|
|
|
+ &v1.Secret{
|
|
|
|
|
+ ObjectMeta: metav1.ObjectMeta{
|
|
|
|
|
+ Name: secretName,
|
|
|
|
|
+ },
|
|
|
|
|
+ Data: map[string][]byte{
|
|
|
|
|
+ string(v1.DockerConfigJsonKey): data,
|
|
|
|
|
+ },
|
|
|
|
|
+ Type: v1.SecretTypeDockerConfigJson,
|
|
|
|
|
+ },
|
|
|
|
|
+ metav1.UpdateOptions{},
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // add secret name to the map
|
|
|
|
|
+ res[key] = secretName
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return res, nil
|
|
|
}
|
|
}
|