github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/api/cloudcontroller/ccv2/security_group.go (about)

     1  package ccv2
     2  
     3  import (
     4  	"bytes"
     5  	"code.cloudfoundry.org/cli/api/cloudcontroller"
     6  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
     7  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/internal"
     8  	"encoding/json"
     9  )
    10  
    11  // SecurityGroup represents a Cloud Controller Security Group.
    12  type SecurityGroup struct {
    13  	// GUID is the unique Security Group identifier.
    14  	GUID string
    15  	// Name is the Security Group's name.
    16  	Name string
    17  	// Rules are the Security Group Rules associated with this Security Group.
    18  	Rules []SecurityGroupRule
    19  	// RunningDefault is true when this Security Group is applied to all running
    20  	// apps in the CF instance.
    21  	RunningDefault bool
    22  	// StagingDefault is true when this Security Group is applied to all staging
    23  	// apps in the CF instance.
    24  	StagingDefault bool
    25  }
    26  
    27  // UnmarshalJSON helps unmarshal a Cloud Controller Security Group response
    28  func (securityGroup *SecurityGroup) UnmarshalJSON(data []byte) error {
    29  	var ccSecurityGroup struct {
    30  		Metadata internal.Metadata `json:"metadata"`
    31  		Entity   struct {
    32  			GUID  string `json:"guid"`
    33  			Name  string `json:"name"`
    34  			Rules []struct {
    35  				Description string `json:"description"`
    36  				Destination string `json:"destination"`
    37  				Ports       string `json:"ports"`
    38  				Protocol    string `json:"protocol"`
    39  				Log         *bool  `json:"log"`
    40  				Code        *int   `json:"code"`
    41  				Type        *int   `json:"type"`
    42  			} `json:"rules"`
    43  			RunningDefault bool `json:"running_default"`
    44  			StagingDefault bool `json:"staging_default"`
    45  		} `json:"entity"`
    46  	}
    47  	err := cloudcontroller.DecodeJSON(data, &ccSecurityGroup)
    48  	if err != nil {
    49  		return err
    50  	}
    51  
    52  	securityGroup.GUID = ccSecurityGroup.Metadata.GUID
    53  	securityGroup.Name = ccSecurityGroup.Entity.Name
    54  	securityGroup.Rules = make([]SecurityGroupRule, len(ccSecurityGroup.Entity.Rules))
    55  	for i, ccRule := range ccSecurityGroup.Entity.Rules {
    56  		securityGroup.Rules[i].Description = ccRule.Description
    57  		securityGroup.Rules[i].Destination = ccRule.Destination
    58  		securityGroup.Rules[i].Ports = ccRule.Ports
    59  		securityGroup.Rules[i].Protocol = ccRule.Protocol
    60  		securityGroup.Rules[i].Log.ParseBoolValue(ccRule.Log)
    61  		securityGroup.Rules[i].Type.ParseIntValue(ccRule.Type)
    62  		securityGroup.Rules[i].Code.ParseIntValue(ccRule.Code)
    63  	}
    64  	securityGroup.RunningDefault = ccSecurityGroup.Entity.RunningDefault
    65  	securityGroup.StagingDefault = ccSecurityGroup.Entity.StagingDefault
    66  	return nil
    67  }
    68  
    69  // MarshalJSON helps marshal a Cloud Controller Security Group request
    70  func (securityGroup SecurityGroup) MarshalJSON() ([]byte, error) {
    71  	type rule struct {
    72  		Description string `json:"description,omitempty"`
    73  		Destination string `json:"destination"`
    74  		Ports       string `json:"ports,omitempty"`
    75  		Protocol    string `json:"protocol"`
    76  		Log         bool   `json:"log"`
    77  		Code        *int   `json:"code,omitempty"`
    78  		Type        *int   `json:"type,omitempty"`
    79  	}
    80  	ccObj := struct {
    81  		Name  string `json:"name,omitempty"`
    82  		Rules []rule `json:"rules,omitempty"`
    83  	}{
    84  		Name:  securityGroup.Name,
    85  		Rules: make([]rule, 0),
    86  	}
    87  	for _, ccRule := range securityGroup.Rules {
    88  		r := rule{
    89  			Protocol:    ccRule.Protocol,
    90  			Description: ccRule.Description,
    91  			Destination: ccRule.Destination,
    92  			Ports:       ccRule.Ports,
    93  		}
    94  		if ccRule.Log.IsSet {
    95  			r.Log = ccRule.Log.Value
    96  		}
    97  		if ccRule.Code.IsSet {
    98  			r.Code = &ccRule.Code.Value
    99  		}
   100  		if ccRule.Type.IsSet {
   101  			r.Type = &ccRule.Type.Value
   102  		}
   103  		ccObj.Rules = append(ccObj.Rules, r)
   104  	}
   105  
   106  	return json.Marshal(ccObj)
   107  }
   108  
   109  // DeleteSecurityGroupSpace disassociates a security group in the running phase
   110  // for the lifecycle, specified by its GUID, from a space, which is also
   111  // specified by its GUID.
   112  func (client *Client) DeleteSecurityGroupSpace(securityGroupGUID string, spaceGUID string) (Warnings, error) {
   113  	request, err := client.newHTTPRequest(requestOptions{
   114  		RequestName: internal.DeleteSecurityGroupSpaceRequest,
   115  		URIParams: Params{
   116  			"security_group_guid": securityGroupGUID,
   117  			"space_guid":          spaceGUID,
   118  		},
   119  	})
   120  
   121  	if err != nil {
   122  		return nil, err
   123  	}
   124  
   125  	response := cloudcontroller.Response{}
   126  
   127  	err = client.connection.Make(request, &response)
   128  	return response.Warnings, err
   129  }
   130  
   131  // DeleteSecurityGroupStagingSpace disassociates a security group in the
   132  // staging phase fo the lifecycle, specified by its GUID, from a space, which
   133  // is also specified by its GUID.
   134  func (client *Client) DeleteSecurityGroupStagingSpace(securityGroupGUID string, spaceGUID string) (Warnings, error) {
   135  	request, err := client.newHTTPRequest(requestOptions{
   136  		RequestName: internal.DeleteSecurityGroupStagingSpaceRequest,
   137  		URIParams: Params{
   138  			"security_group_guid": securityGroupGUID,
   139  			"space_guid":          spaceGUID,
   140  		},
   141  	})
   142  
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  
   147  	response := cloudcontroller.Response{}
   148  
   149  	err = client.connection.Make(request, &response)
   150  	return response.Warnings, err
   151  }
   152  
   153  // GetSecurityGroups returns a list of Security Groups based off the provided
   154  // filters.
   155  func (client *Client) GetSecurityGroups(filters ...Filter) ([]SecurityGroup, Warnings, error) {
   156  	request, err := client.newHTTPRequest(requestOptions{
   157  		RequestName: internal.GetSecurityGroupsRequest,
   158  		Query:       ConvertFilterParameters(filters),
   159  	})
   160  
   161  	if err != nil {
   162  		return nil, nil, err
   163  	}
   164  
   165  	var securityGroupsList []SecurityGroup
   166  	warnings, err := client.paginate(request, SecurityGroup{}, func(item interface{}) error {
   167  		if securityGroup, ok := item.(SecurityGroup); ok {
   168  			securityGroupsList = append(securityGroupsList, securityGroup)
   169  		} else {
   170  			return ccerror.UnknownObjectInListError{
   171  				Expected:   SecurityGroup{},
   172  				Unexpected: item,
   173  			}
   174  		}
   175  		return nil
   176  	})
   177  
   178  	return securityGroupsList, warnings, err
   179  }
   180  
   181  // GetSpaceSecurityGroups returns the running Security Groups associated with
   182  // the provided Space GUID.
   183  func (client *Client) GetSpaceSecurityGroups(spaceGUID string, filters ...Filter) ([]SecurityGroup, Warnings, error) {
   184  	return client.getSpaceSecurityGroupsBySpaceAndLifecycle(spaceGUID, internal.GetSpaceSecurityGroupsRequest, filters)
   185  }
   186  
   187  // GetSpaceStagingSecurityGroups returns the staging Security Groups
   188  // associated with the provided Space GUID.
   189  func (client *Client) GetSpaceStagingSecurityGroups(spaceGUID string, filters ...Filter) ([]SecurityGroup, Warnings, error) {
   190  	return client.getSpaceSecurityGroupsBySpaceAndLifecycle(spaceGUID, internal.GetSpaceStagingSecurityGroupsRequest, filters)
   191  }
   192  
   193  // UpdateSecurityGroupSpace associates a security group in the running phase
   194  // for the lifecycle, specified by its GUID, from a space, which is also
   195  // specified by its GUID.
   196  func (client *Client) UpdateSecurityGroupSpace(securityGroupGUID string, spaceGUID string) (Warnings, error) {
   197  	request, err := client.newHTTPRequest(requestOptions{
   198  		RequestName: internal.PutSecurityGroupSpaceRequest,
   199  		URIParams: Params{
   200  			"security_group_guid": securityGroupGUID,
   201  			"space_guid":          spaceGUID,
   202  		},
   203  	})
   204  
   205  	if err != nil {
   206  		return nil, err
   207  	}
   208  
   209  	response := cloudcontroller.Response{}
   210  
   211  	err = client.connection.Make(request, &response)
   212  	return response.Warnings, err
   213  }
   214  
   215  // UpdateSecurityGroupStagingSpace associates a security group in the staging
   216  // phase for the lifecycle, specified by its GUID, from a space, which is also
   217  // specified by its GUID.
   218  func (client *Client) UpdateSecurityGroupStagingSpace(securityGroupGUID string, spaceGUID string) (Warnings, error) {
   219  	request, err := client.newHTTPRequest(requestOptions{
   220  		RequestName: internal.PutSecurityGroupStagingSpaceRequest,
   221  		URIParams: Params{
   222  			"security_group_guid": securityGroupGUID,
   223  			"space_guid":          spaceGUID,
   224  		},
   225  	})
   226  
   227  	if err != nil {
   228  		return nil, err
   229  	}
   230  
   231  	response := cloudcontroller.Response{}
   232  
   233  	err = client.connection.Make(request, &response)
   234  	return response.Warnings, err
   235  }
   236  
   237  func (client *Client) getSpaceSecurityGroupsBySpaceAndLifecycle(spaceGUID string, lifecycle string, filters []Filter) ([]SecurityGroup, Warnings, error) {
   238  	request, err := client.newHTTPRequest(requestOptions{
   239  		RequestName: lifecycle,
   240  		URIParams:   map[string]string{"space_guid": spaceGUID},
   241  		Query:       ConvertFilterParameters(filters),
   242  	})
   243  	if err != nil {
   244  		return nil, nil, err
   245  	}
   246  
   247  	var securityGroupsList []SecurityGroup
   248  	warnings, err := client.paginate(request, SecurityGroup{}, func(item interface{}) error {
   249  		if securityGroup, ok := item.(SecurityGroup); ok {
   250  			securityGroupsList = append(securityGroupsList, securityGroup)
   251  		} else {
   252  			return ccerror.UnknownObjectInListError{
   253  				Expected:   SecurityGroup{},
   254  				Unexpected: item,
   255  			}
   256  		}
   257  		return err
   258  	})
   259  
   260  	return securityGroupsList, warnings, err
   261  }
   262  
   263  // GetRunningSecurityGroups returns back a list of running security groups based off of the
   264  // provided filters.
   265  func (client *Client) GetRunningSecurityGroups(filters ...Filter) ([]SecurityGroup, Warnings, error) {
   266  	request, err := client.newHTTPRequest(requestOptions{
   267  		RequestName: internal.GetConfigRunningSecurityGroupsRequest,
   268  		Query:       ConvertFilterParameters(filters),
   269  	})
   270  	if err != nil {
   271  		return nil, nil, err
   272  	}
   273  
   274  	var fullObjList []SecurityGroup
   275  	warnings, err := client.paginate(request, SecurityGroup{}, func(item interface{}) error {
   276  		if app, ok := item.(SecurityGroup); ok {
   277  			fullObjList = append(fullObjList, app)
   278  		} else {
   279  			return ccerror.UnknownObjectInListError{
   280  				Expected:   SecurityGroup{},
   281  				Unexpected: item,
   282  			}
   283  		}
   284  		return nil
   285  	})
   286  
   287  	return fullObjList, warnings, err
   288  }
   289  
   290  // BindSecurityGroup bind the security group with the given GUID.
   291  func (client *Client) BindRunningSecurityGroup(guid string) (Warnings, error) {
   292  	request, err := client.newHTTPRequest(requestOptions{
   293  		RequestName: internal.PutConfigRunningSecurityGroupRequest,
   294  		URIParams:   Params{"security_group_guid": guid},
   295  	})
   296  	if err != nil {
   297  		return nil, err
   298  	}
   299  
   300  	response := cloudcontroller.Response{
   301  	}
   302  
   303  	err = client.connection.Make(request, &response)
   304  	return response.Warnings, err
   305  }
   306  
   307  // UnbindSecurityGroup delete a security group
   308  func (client *Client) UnbindRunningSecurityGroup(guid string) (Warnings, error) {
   309  	request, err := client.newHTTPRequest(requestOptions{
   310  		RequestName: internal.DeleteConfigRunningSecurityGroupRequest,
   311  		URIParams: Params{
   312  			"security_group_guid": guid,
   313  		},
   314  	})
   315  	if err != nil {
   316  		return nil, err
   317  	}
   318  
   319  	response := cloudcontroller.Response{}
   320  
   321  	err = client.connection.Make(request, &response)
   322  	return response.Warnings, err
   323  }
   324  
   325  // GetSecurityGroups returns back a list of staging security groups based off of the
   326  // provided filters.
   327  func (client *Client) GetStagingSecurityGroups(filters ...Filter) ([]SecurityGroup, Warnings, error) {
   328  	request, err := client.newHTTPRequest(requestOptions{
   329  		RequestName: internal.GetConfigStagingSecurityGroupsRequest,
   330  		Query:       ConvertFilterParameters(filters),
   331  	})
   332  	if err != nil {
   333  		return nil, nil, err
   334  	}
   335  
   336  	var fullObjList []SecurityGroup
   337  	warnings, err := client.paginate(request, SecurityGroup{}, func(item interface{}) error {
   338  		if app, ok := item.(SecurityGroup); ok {
   339  			fullObjList = append(fullObjList, app)
   340  		} else {
   341  			return ccerror.UnknownObjectInListError{
   342  				Expected:   SecurityGroup{},
   343  				Unexpected: item,
   344  			}
   345  		}
   346  		return nil
   347  	})
   348  
   349  	return fullObjList, warnings, err
   350  }
   351  
   352  // BindSecurityGroup bind the security group with the given GUID.
   353  func (client *Client) BindStagingSecurityGroup(guid string) (Warnings, error) {
   354  	request, err := client.newHTTPRequest(requestOptions{
   355  		RequestName: internal.PutConfigStagingSecurityGroupRequest,
   356  		URIParams:   Params{"security_group_guid": guid},
   357  	})
   358  	if err != nil {
   359  		return nil, err
   360  	}
   361  
   362  	response := cloudcontroller.Response{
   363  	}
   364  
   365  	err = client.connection.Make(request, &response)
   366  	return response.Warnings, err
   367  }
   368  
   369  // UnbindSecurityGroup delete a security group
   370  func (client *Client) UnbindStagingSecurityGroup(guid string) (Warnings, error) {
   371  	request, err := client.newHTTPRequest(requestOptions{
   372  		RequestName: internal.DeleteConfigStagingSecurityGroupRequest,
   373  		URIParams: Params{
   374  			"security_group_guid": guid,
   375  		},
   376  	})
   377  	if err != nil {
   378  		return nil, err
   379  	}
   380  
   381  	response := cloudcontroller.Response{}
   382  
   383  	err = client.connection.Make(request, &response)
   384  	return response.Warnings, err
   385  }
   386  
   387  // CreateSecurityGroup creates a cloud controller security group in with the given settings.
   388  func (client *Client) CreateSecurityGroup(securityGroup SecurityGroup) (SecurityGroup, Warnings, error) {
   389  	body, err := json.Marshal(securityGroup)
   390  	if err != nil {
   391  		return SecurityGroup{}, nil, err
   392  	}
   393  
   394  	request, err := client.newHTTPRequest(requestOptions{
   395  		RequestName: internal.PostSecurityGroupsRequest,
   396  		Body:        bytes.NewReader(body),
   397  	})
   398  	if err != nil {
   399  		return SecurityGroup{}, nil, err
   400  	}
   401  
   402  	var updatedObj SecurityGroup
   403  	response := cloudcontroller.Response{
   404  		DecodeJSONResponseInto: &updatedObj,
   405  	}
   406  
   407  	err = client.connection.Make(request, &response)
   408  	return updatedObj, response.Warnings, err
   409  }
   410  
   411  // UpdateSecurityGroup updates the security group with the given GUID.
   412  func (client *Client) UpdateSecurityGroup(securityGroup SecurityGroup) (SecurityGroup, Warnings, error) {
   413  	body, err := json.Marshal(securityGroup)
   414  	if err != nil {
   415  		return SecurityGroup{}, nil, err
   416  	}
   417  
   418  	request, err := client.newHTTPRequest(requestOptions{
   419  		RequestName: internal.PostSecurityGroupRequest,
   420  		URIParams:   Params{"security_group_guid": securityGroup.GUID},
   421  		Body:        bytes.NewReader(body),
   422  	})
   423  	if err != nil {
   424  		return SecurityGroup{}, nil, err
   425  	}
   426  
   427  	var updatedObj SecurityGroup
   428  	response := cloudcontroller.Response{
   429  		DecodeJSONResponseInto: &updatedObj,
   430  	}
   431  
   432  	err = client.connection.Make(request, &response)
   433  	return updatedObj, response.Warnings, err
   434  }
   435  
   436  // GetSecurityGroup returns back a security group.
   437  func (client *Client) GetSecurityGroup(guid string) (SecurityGroup, Warnings, error) {
   438  	request, err := client.newHTTPRequest(requestOptions{
   439  		RequestName: internal.GetSecurityGroupRequest,
   440  		URIParams: Params{
   441  			"security_group_guid": guid,
   442  		},
   443  	})
   444  	if err != nil {
   445  		return SecurityGroup{}, nil, err
   446  	}
   447  
   448  	var obj SecurityGroup
   449  	response := cloudcontroller.Response{
   450  		DecodeJSONResponseInto: &obj,
   451  	}
   452  
   453  	err = client.connection.Make(request, &response)
   454  	return obj, response.Warnings, err
   455  }
   456  
   457  // DeleteSecurityGroup delete a security group
   458  func (client *Client) DeleteSecurityGroup(guid string) (Warnings, error) {
   459  	request, err := client.newHTTPRequest(requestOptions{
   460  		RequestName: internal.DeleteSecurityGroupRequest,
   461  		URIParams: Params{
   462  			"security_group_guid": guid,
   463  		},
   464  	})
   465  	if err != nil {
   466  		return nil, err
   467  	}
   468  
   469  	response := cloudcontroller.Response{}
   470  
   471  	err = client.connection.Make(request, &response)
   472  	return response.Warnings, err
   473  }