diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 26af92a549..f17d5af1b0 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -4881,7 +4881,7 @@ class InstanceSerializer(BaseSerializer): class Meta: model = Instance - read_only_fields = ('ip_address', 'uuid', 'version', 'node_state') + read_only_fields = ('ip_address', 'uuid', 'version') fields = ( 'id', 'type', @@ -4959,6 +4959,21 @@ class InstanceSerializer(BaseSerializer): return value + def validate_node_state(self, value): + if self.instance: + if value != self.instance.node_state: + if not settings.IS_K8S: + raise serializers.ValidationError("Can only change the state on Kubernetes or OpenShift.") + if value != Instance.States.DEPROVISIONING: + raise serializers.ValidationError("Can only change instances to the 'deprovisioning' state.") + if self.instance.node_type not in (Instance.Types.EXECUTION,): + raise serializers.ValidationError("Can only deprovision execution nodes.") + else: + if value and value != Instance.States.INSTALLED: + raise serializers.ValidationError("Can only create instances in the 'installed' state.") + + return value + class InstanceHealthCheckSerializer(BaseSerializer): class Meta: diff --git a/awx/api/views/__init__.py b/awx/api/views/__init__.py index 7c8b6aaffc..7865527a2b 100644 --- a/awx/api/views/__init__.py +++ b/awx/api/views/__init__.py @@ -384,6 +384,9 @@ class InstanceDetail(RetrieveUpdateAPIView): r = super(InstanceDetail, self).update(request, *args, **kwargs) if status.is_success(r.status_code): obj = self.get_object() + if obj.node_state == models.Instance.States.DEPROVISIONING: + models.InstanceLink.objects.filter(target=obj).update(link_state=models.InstanceLink.States.REMOVING) + models.InstanceLink.objects.filter(source=obj).update(link_state=models.InstanceLink.States.REMOVING) obj.set_capacity_value() obj.save(update_fields=['capacity']) r.data = serializers.InstanceSerializer(obj, context=self.get_serializer_context()).to_representation(obj)