from nailgun.api.v1.handlers import base
from nailgun import consts
from nailgun.db import db
from nailgun import objects
from nailgun import utils

from octane import validators


class ClusterCloneHandler(base.BaseHandler):
    single = objects.Cluster
    validator = validators.ClusterCloneValidator

    @base.content
    def POST(self, cluster_id):
        params = self.checked_data()
        cluster = self.get_object_or_404(self.single, cluster_id)
        release = self.get_object_or_404(objects.Release, params["release_id"])
        data = {
            "name": params["name"],
            "mode": cluster.mode,
            "status": consts.CLUSTER_STATUSES.new,
            "net_provider": cluster.net_provider,
            "grouping": consts.CLUSTER_GROUPING.roles,
            "release_id": release.id,
        }
        if cluster.net_provider == consts.CLUSTER_NET_PROVIDERS.neutron:
            data["net_segmentation_type"] = \
                cluster.network_config.segmentation_type
            data["net_l23_provider"] = cluster.network_config.net_l23_provider
        clone = self.single.create(data)
        clone.attributes.generated = utils.dict_merge(
            clone.attributes.generated,
            cluster.attributes.generated)
        db().flush()
        return self.single.to_json(clone)

@@ -1,20 +1,33 @@
+import copy%0A%0A
 from nailgun.api.v1.
@@ -361,16 +361,70 @@
 er_id):%0A
+        %22%22%22Create a clone of the cluster.%0A        %22%22%22%0A
         
@@ -1334,59 +1334,770 @@
     
-db().flush()%0A        return self.single.to_json(clone)
+clone.attributes.editable = self.merge_attributes(%0A            cluster.attributes.editable,%0A            clone.attributes.editable)%0A        db().flush()%0A        return self.single.to_json(clone)%0A%0A    @staticmethod%0A    def merge_attributes(a, b):%0A        %22%22%22Merge values of editable attributes.%0A%0A        :param a: a dict of editable attributes%0A        :param b: a dict of editable attributes%0A        %22%22%22%0A        attrs = copy.deepcopy(b)%0A        for section, pairs in attrs.iteritems():%0A            if section not in a:%0A                continue%0A            a_values = a%5Bsection%5D%0A            for key, values in pairs.iteritems():%0A                if key != %22metadata%22 and key in a_values:%0A                    values%5B%22value%22%5D = a_values%5Bkey%5D%5B%22value%22%5D%0A        return attrs
 %0A

Copy editable attributes of the cluster