aboutsummaryrefslogtreecommitdiffstats
path: root/src/dcm/pkg/module
diff options
context:
space:
mode:
Diffstat (limited to 'src/dcm/pkg/module')
-rw-r--r--src/dcm/pkg/module/apply.go182
-rw-r--r--src/dcm/pkg/module/quota.go6
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"`