func (r *Firewall) Apply(actual, expected cloud.Resource, immutable *cluster.Cluster) (*cluster.Cluster, cloud.Resource, error) {
	logger.Debug("firewall.Apply")
	expectedResource := expected.(*Firewall)
	actualResource := actual.(*Firewall)

	isEqual, err := compare.IsEqual(actualResource, expectedResource)
	if err != nil {
		return nil, nil, err
	}
	if isEqual {
		return immutable, expected, nil
	}

	firewallRequest := godo.FirewallRequest{
		Name:          expectedResource.Name,
		InboundRules:  convertInRuleType(expectedResource.InboundRules),
		OutboundRules: convertOutRuleType(expectedResource.OutboundRules),
		DropletIDs:    expectedResource.DropletIDs,
		Tags:          expectedResource.Tags,
	}

	// Make sure Droplets are fully created before applying a firewall
	machineProviderConfigs := immutable.MachineProviderConfigs()
	for _, machineProviderConfig := range machineProviderConfigs {
		for i := 0; i <= TagsGetAttempts; i++ {
			active := true
			droplets, _, err := Sdk.Client.Droplets.ListByTag(context.TODO(), machineProviderConfig.ServerPool.Name, &godo.ListOptions{})
			if err != nil {
				logger.Debug("Hanging for droplets to get created.. (%v)", err)
				time.Sleep(time.Duration(TagsGetTimeout) * time.Second)
				continue
			}
			if len(droplets) == 0 {
				continue
			}
			for _, d := range droplets {
				if d.Status != "active" {
					active = false
					break
				}
			}
			if !active {
				logger.Debug("Waiting for droplets to become active..")
				time.Sleep(time.Duration(TagsGetTimeout) * time.Second)
				continue
			}
			break
		}
	}

	firewall, _, err := Sdk.Client.Firewalls.Create(context.TODO(), &firewallRequest)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to create the firewall err: %v", err)
	}
	logger.Success("Created Firewall [%s]", firewall.ID)
	newResource := &Firewall{
		Shared: Shared{
			CloudID: firewall.ID,
			Name:    r.Name,
			Tags:    r.Tags,
		},
		DropletIDs:    r.DropletIDs,
		FirewallID:    firewall.ID,
		InboundRules:  r.InboundRules,
		OutboundRules: r.OutboundRules,
		Created:       r.Created,
	}

	newCluster := r.immutableRender(newResource, immutable)
	return newCluster, newResource, nil
}
func (r *Firewall) Apply(actual, expected cloud.Resource, immutable *cluster.Cluster) (*cluster.Cluster, cloud.Resource, error) {
	logger.Debug("firewall.Apply")
	expectedResource := expected.(*Firewall)
	actualResource := actual.(*Firewall)

	isEqual, err := compare.IsEqual(actualResource, expectedResource)
	if err != nil {
		return nil, nil, err
	}
	if isEqual {
		return immutable, expected, nil
	}

	firewallRequest := godo.FirewallRequest{
		Name:          expectedResource.Name,
		InboundRules:  convertInRuleType(expectedResource.InboundRules),
		OutboundRules: convertOutRuleType(expectedResource.OutboundRules),
		DropletIDs:    expectedResource.DropletIDs,
		Tags:          expectedResource.Tags,
	}

	
	machineProviderConfigs := immutable.MachineProviderConfigs()
	for _, machineProviderConfig := range machineProviderConfigs {
		for i := 0; i <= TagsGetAttempts; i++ {
			active := true
			droplets, _, err := Sdk.Client.Droplets.ListByTag(context.TODO(), machineProviderConfig.ServerPool.Name, &godo.ListOptions{})
			if err != nil {
				logger.Debug("Hanging for droplets to get created.. (%v)", err)
				time.Sleep(time.Duration(TagsGetTimeout) * time.Second)
				continue
			}
			if len(droplets) == 0 {
				continue
			}
			for _, d := range droplets {
				if d.Status != "active" {
					active = false
					break
				}
			}
			if !active {
				logger.Debug("Waiting for droplets to become active..")
				time.Sleep(time.Duration(TagsGetTimeout) * time.Second)
				continue
			}
			break
		}
	}

	firewall, _, err := Sdk.Client.Firewalls.Create(context.TODO(), &firewallRequest)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to create the firewall err: %v", err)
	}
	logger.Success("Created Firewall [%s]", firewall.ID)
	newResource := &Firewall{
		Shared: Shared{
			CloudID: firewall.ID,
			Name:    r.Name,
			Tags:    r.Tags,
		},
		DropletIDs:    r.DropletIDs,
		FirewallID:    firewall.ID,
		InboundRules:  r.InboundRules,
		OutboundRules: r.OutboundRules,
		Created:       r.Created,
	}

	newCluster := r.immutableRender(newResource, immutable)
	return newCluster, newResource, nil
}
func ( r * Firewall ) Apply ( actual , expected cloud . Resource , immutable * cluster . Cluster ) ( * cluster . Cluster , cloud . Resource , error ) { logger . Debug ( " " ) expectedResource := expected . ( * Firewall ) actualResource := actual . ( * Firewall ) isEqual , err := compare . IsEqual ( actualResource , expectedResource ) if err != nil { return nil , nil , err } if isEqual { return immutable , expected , nil } firewallRequest := godo . FirewallRequest { Name : expectedResource . Name , InboundRules : convertInRuleType ( expectedResource . InboundRules ) , OutboundRules : convertOutRuleType ( expectedResource . OutboundRules ) , DropletIDs : expectedResource . DropletIDs , Tags : expectedResource . Tags , } // Make sure Droplets are fully created before applying a firewall machineProviderConfigs := immutable . MachineProviderConfigs ( ) for _ , machineProviderConfig := range machineProviderConfigs { for i := 0 ; i <= TagsGetAttempts ; i ++ { active := true droplets , _ , err := Sdk . Client . Droplets . ListByTag ( context . TODO ( ) , machineProviderConfig . ServerPool . Name , & godo . ListOptions { } ) if err != nil { logger . Debug ( " " , err ) time . Sleep ( time . Duration ( TagsGetTimeout ) * time . Second ) continue } if len ( droplets ) == 0 { continue } for _ , d := range droplets { if d . Status != " " { active = false break } } if ! active { logger . Debug ( " " ) time . Sleep ( time . Duration ( TagsGetTimeout ) * time . Second ) continue } break } } firewall , _ , err := Sdk . Client . Firewalls . Create ( context . TODO ( ) , & firewallRequest ) if err != nil { return nil , nil , fmt . Errorf ( " " , err ) } logger . Success ( " " , firewall . ID ) newResource := & Firewall { Shared : Shared { CloudID : firewall . ID , Name : r . Name , Tags : r . Tags , } , DropletIDs : r . DropletIDs , FirewallID : firewall . ID , InboundRules : r . InboundRules , OutboundRules : r . OutboundRules , Created : r . Created , } newCluster := r . immutableRender ( newResource , immutable ) return newCluster , newResource , nil }
// Apply will compare the actual and expected firewall config, if needed it will create the firewall.
Apply will compare the actual and expected firewall config if needed it will create the firewall .