diff options
Diffstat (limited to 'src/dcm/pkg')
-rw-r--r-- | src/dcm/pkg/module/apply.go | 182 | ||||
-rw-r--r-- | src/dcm/pkg/module/quota.go | 6 |
2 files changed, 160 insertions, 28 deletions
diff --git a/src/dcm/pkg/module/apply.go b/src/dcm/pkg/module/apply.go index 84eb7ef7..a866934a 100644 --- a/src/dcm/pkg/module/apply.go +++ b/src/dcm/pkg/module/apply.go @@ -28,11 +28,15 @@ import ( "strings" "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext" + "github.com/onap/multicloud-k8s/src/orchestrator/pkg/appcontext/subresources" "github.com/onap/multicloud-k8s/src/orchestrator/pkg/grpc/installappclient" + "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/db" log "github.com/onap/multicloud-k8s/src/orchestrator/pkg/infra/logutils" "github.com/onap/multicloud-k8s/src/orchestrator/pkg/module/controller" pkgerrors "github.com/pkg/errors" "gopkg.in/yaml.v2" + certificatesv1beta1 "k8s.io/api/certificates/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) // rsyncName denotes the name of the rsync controller @@ -56,8 +60,10 @@ type MetaDatas struct { type Specs struct { Request string `yaml:"request,omitempty"` Usages []string `yaml:"usages,omitempty"` - //Hard logicalcloud.QSpec `yaml:"hard,omitempty"` - Hard QSpec `yaml:"hard,omitempty"` + // TODO: validate quota keys + // //Hard logicalcloud.QSpec `yaml:"hard,omitempty"` + // Hard QSpec `yaml:"hard,omitempty"` + Hard map[string]string `yaml:"hard,omitempty"` } type RoleRules struct { @@ -152,12 +158,10 @@ func createRoleBinding(logicalcloud LogicalCloud) (string, error) { } return string(rBData), nil - } func createQuota(quota []Quota, namespace string) (string, error) { lcQuota := quota[0] - q := Resource{ ApiVersion: "v1", Kind: "ResourceQuota", @@ -176,23 +180,22 @@ func createQuota(quota []Quota, namespace string) (string, error) { } return string(qData), nil - } -func createUserCSR(logicalcloud LogicalCloud) (string, error) { +func createUserCSR(logicalcloud LogicalCloud) (string, string, error) { KEYSIZE := 4096 userName := logicalcloud.Specification.User.UserName key, err := rsa.GenerateKey(rand.Reader, KEYSIZE) if err != nil { - return "", err + return "", "", err } csrTemplate := x509.CertificateRequest{Subject: pkix.Name{CommonName: userName}} csrCert, err := x509.CreateCertificateRequest(rand.Reader, &csrTemplate, key) if err != nil { - return "", err + return "", "", err } //Encode csr @@ -205,8 +208,8 @@ func createUserCSR(logicalcloud LogicalCloud) (string, error) { ApiVersion: "certificates.k8s.io/v1beta1", Kind: "CertificateSigningRequest", MetaData: MetaDatas{ - Name: strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "-user-csr"}, ""), - Namespace: logicalcloud.Specification.NameSpace, + Name: strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "-user-csr"}, ""), + // Namespace: logicalcloud.Specification.NameSpace, }, Specification: Specs{ Request: base64.StdEncoding.EncodeToString(csr), @@ -216,11 +219,31 @@ func createUserCSR(logicalcloud LogicalCloud) (string, error) { csrData, err := yaml.Marshal(&csrObj) if err != nil { - return "", err + return "", "", err + } + + keyData := base64.StdEncoding.EncodeToString(pem.EncodeToMemory( + &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(key), + }, + )) + if err != nil { + return "", "", err } - return string(csrData), nil + return string(csrData), string(keyData), nil +} +func createApprovalSubresource(logicalcloud LogicalCloud) (string, error) { + subresource := subresources.ApprovalSubresource{ + Message: "Approved for Logical Cloud authentication", + Reason: "LogicalCloud", + Type: string(certificatesv1beta1.CertificateApproved), + LastUpdateTime: metav1.Now().Format("2006-01-02T15:04:05Z"), + } + csrData, err := json.Marshal(subresource) + return string(csrData), err } /* @@ -243,7 +266,27 @@ func queryDBAndSetRsyncInfo() (installappclient.RsyncInfo, error) { } /* -callRsyncUninstall method shall take in the app context id and invoke the rsync service via grpc +callRsyncInstall method shall take in the app context id and invokes the rsync service via grpc +*/ +func callRsyncInstall(contextid interface{}) error { + rsyncInfo, err := queryDBAndSetRsyncInfo() + log.Info("Calling the Rsync ", log.Fields{ + "RsyncName": rsyncInfo.RsyncName, + }) + if err != nil { + return err + } + + appContextID := fmt.Sprintf("%v", contextid) + err = installappclient.InvokeInstallApp(appContextID) + if err != nil { + return err + } + return nil +} + +/* +callRsyncUninstall method shall take in the app context id and invokes the rsync service via grpc */ func callRsyncUninstall(contextid interface{}) error { rsyncInfo, err := queryDBAndSetRsyncInfo() @@ -262,20 +305,12 @@ func callRsyncUninstall(contextid interface{}) error { return nil } -// TODO: -// Install istio -// Store user key for user creation -// Code to run kubectl commands for user -// kubectl certificate approve lc1-user-cert -// kubectl get csr lc1-user-cert -o jsonpath='{.status.certificate}' | base64 --decode > user.crt -// kubectl config set-credentials user --client-certificate=<user.crt> --client-key=<user.key> -// kubectl config set-context user-context --cluster=cluster-name --namespace=lc1 --user=user - func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster, quotaList []Quota) error { APP := "logical-cloud" logicalCloudName := logicalcloud.MetaData.LogicalCloudName + project := "test-project" // FIXME(igordc): temporary, need to do some rework in the LC structs //Resource Names namespaceName := strings.Join([]string{logicalcloud.MetaData.LogicalCloudName, "+namespace"}, "") @@ -305,11 +340,13 @@ func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster, return pkgerrors.Wrap(err, "Error Creating Quota YAML for logical cloud") } - csr, err := createUserCSR(logicalcloud) + csr, key, err := createUserCSR(logicalcloud) if err != nil { - return pkgerrors.Wrap(err, "Error Creating User CSR for logical cloud") + return pkgerrors.Wrap(err, "Error Creating User CSR and Key for logical cloud") } + approval, err := createApprovalSubresource(logicalcloud) + context := appcontext.AppContext{} ctxVal, err := context.InitAppContext() if err != nil { @@ -366,7 +403,7 @@ func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster, } // Add csr resource to each cluster - _, err = context.AddResource(clusterHandle, csrName, csr) + csrHandle, err := context.AddResource(clusterHandle, csrName, csr) if err != nil { cleanuperr := context.DeleteCompositeApp() if cleanuperr != nil { @@ -379,6 +416,36 @@ func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster, return pkgerrors.Wrap(err, "Error adding CSR Resource to AppContext") } + // Add csr approval as a subresource of csr: + _, err = context.AddLevelValue(csrHandle, "subresource/approval", approval) + if err != nil { + cleanuperr := context.DeleteCompositeApp() + if cleanuperr != nil { + log.Warn("Error cleaning AppContext after add CSR approval failure", log.Fields{ + "cluster-provider": cluster.Specification.ClusterProvider, + "cluster": cluster.Specification.ClusterName, + "logical-cloud": logicalCloudName, + }) + } + return pkgerrors.Wrap(err, "Error approving CSR via AppContext") + } + + // Add private key to MongoDB + lckey := LogicalCloudKey{ + LogicalCloudName: logicalcloud.MetaData.LogicalCloudName, + Project: project, + } + err = db.DBconn.Insert("orchestrator", lckey, nil, "privatekey", key) + if err != nil { + cleanuperr := context.DeleteCompositeApp() + if cleanuperr != nil { + log.Warn("Error cleaning AppContext after DB insert failure", log.Fields{ + "logical-cloud": logicalcloud.MetaData.LogicalCloudName, + }) + } + return pkgerrors.Wrap(err, "Error adding private key to DB") + } + // Add Role resource to each cluster _, err = context.AddResource(clusterHandle, roleName, role) if err != nil { @@ -421,16 +488,29 @@ func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster, return pkgerrors.Wrap(err, "Error adding quota Resource to AppContext") } + // Add Subresource Order and Subresource Dependency + subresOrder, err := json.Marshal(map[string][]string{"subresorder": []string{"approval"}}) + if err != nil { + return pkgerrors.Wrap(err, "Error creating subresource order JSON") + } + subresDependency, err := json.Marshal(map[string]map[string]string{"subresdependency": map[string]string{"approval": "go"}}) + // Add Resource Order and Resource Dependency resOrder, err := json.Marshal(map[string][]string{"resorder": []string{namespaceName, quotaName, csrName, roleName, roleBindingName}}) if err != nil { return pkgerrors.Wrap(err, "Error creating resource order JSON") } - resDependency, err := json.Marshal(map[string]map[string]string{"resdependency": map[string]string{namespaceName: "go", quotaName: strings.Join([]string{"wait on ", namespaceName}, ""), csrName: strings.Join([]string{"wait on ", quotaName}, ""), roleName: strings.Join([]string{"wait on ", csrName}, ""), roleBindingName: strings.Join([]string{"wait on ", roleName}, "")}}) + // Add App Order and App Dependency + appOrder, err := json.Marshal(map[string][]string{"apporder": []string{APP}}) + if err != nil { + return pkgerrors.Wrap(err, "Error creating resource order JSON") + } + appDependency, err := json.Marshal(map[string]map[string]string{"appdependency": map[string]string{APP: "go"}}) + if err != nil { return pkgerrors.Wrap(err, "Error creating resource dependency JSON") } @@ -461,6 +541,56 @@ func CreateEtcdContext(logicalcloud LogicalCloud, clusterList []Cluster, return pkgerrors.Wrap(err, "Error adding instruction dependency to AppContext") } + _, err = context.AddInstruction(csrHandle, "subresource", "order", string(subresOrder)) + if err != nil { + cleanuperr := context.DeleteCompositeApp() + if cleanuperr != nil { + log.Warn("Error cleaning AppContext after add instruction failure", log.Fields{ + "cluster-provider": cluster.Specification.ClusterProvider, + "cluster": cluster.Specification.ClusterName, + "logical-cloud": logicalCloudName, + }) + } + return pkgerrors.Wrap(err, "Error adding instruction order to AppContext") + } + + _, err = context.AddInstruction(csrHandle, "subresource", "dependency", string(subresDependency)) + if err != nil { + cleanuperr := context.DeleteCompositeApp() + if cleanuperr != nil { + log.Warn("Error cleaning AppContext after add instruction failure", log.Fields{ + "cluster-provider": cluster.Specification.ClusterProvider, + "cluster": cluster.Specification.ClusterName, + "logical-cloud": logicalCloudName, + }) + } + return pkgerrors.Wrap(err, "Error adding instruction dependency to AppContext") + } + + // Add App-level Order and Dependency + _, err = context.AddInstruction(handle, "app", "order", string(appOrder)) + _, err = context.AddInstruction(handle, "app", "dependency", string(appDependency)) + } + // save the context in the logicalcloud db record + lckey := LogicalCloudKey{ + LogicalCloudName: logicalcloud.MetaData.LogicalCloudName, + Project: project, + } + err = db.DBconn.Insert("orchestrator", lckey, nil, "lccontext", ctxVal) + if err != nil { + cleanuperr := context.DeleteCompositeApp() + if cleanuperr != nil { + log.Warn("Error cleaning AppContext after DB insert failure", log.Fields{ + "logical-cloud": logicalcloud.MetaData.LogicalCloudName, + }) + } + return pkgerrors.Wrap(err, "Error adding AppContext to DB") + } + + // call resource synchronizer to instantiate the CRs in the cluster + err = callRsyncInstall(ctxVal) + if err != nil { + return err } return nil diff --git a/src/dcm/pkg/module/quota.go b/src/dcm/pkg/module/quota.go index 8e15a794..c961fdfc 100644 --- a/src/dcm/pkg/module/quota.go +++ b/src/dcm/pkg/module/quota.go @@ -22,8 +22,9 @@ import ( // Quota contains the parameters needed for a Quota type Quota struct { - MetaData QMetaDataList `json:"metadata"` - Specification QSpec `json:"spec"` + MetaData QMetaDataList `json:"metadata"` + // Specification QSpec `json:"spec"` + Specification map[string]string `json:"spec"` } // MetaData contains the parameters needed for metadata @@ -32,6 +33,7 @@ type QMetaDataList struct { Description string `json:"description"` } +// TODO: use QSpec fields to validate quota keys // Spec contains the parameters needed for spec type QSpec struct { LimitsCPU string `json:"limits.cpu"` |