44 "context"
55 "encoding/json"
66 "fmt"
7+ "strconv"
78
89 cfv3 "github.com/cloudfoundry/go-cfclient/v3/client"
910 cfconfig "github.com/cloudfoundry/go-cfclient/v3/config"
@@ -64,6 +65,8 @@ func (c *CFClient) GetResourcesByType(ctx context.Context, resourceType string,
6465 return c .getApps (ctx , filter )
6566 case v1alpha1 .RouteKind :
6667 return c .getRoutes (ctx , filter )
68+ case v1alpha1 .ServiceInstance_Kind :
69+ return c .getServiceInstances (ctx , filter )
6770 default :
6871 return nil , fmt .Errorf ("unsupported resource type: %s" , resourceType )
6972 }
@@ -146,28 +149,43 @@ func (c *CFClient) getOrganizations(ctx context.Context, filter map[string]strin
146149 return results , nil
147150}
148151
152+ // getSpaceReference retrieves a space reference by name
153+ func (c * CFClient ) getSpaceReference (ctx context.Context , filter map [string ]string ) (string , error ) {
154+ spaceName , ok := filter ["space" ]
155+ if ! ok {
156+ return "" , fmt .Errorf ("space-reference filter is required" )
157+ }
158+
159+ spaceRefFilter := cfv3.SpaceListOptions {Names : cfv3.Filter {Values : []string {spaceName }}}
160+ spaceRef , err := c .client .Spaces .ListAll (ctx , & spaceRefFilter )
161+ if err != nil {
162+ return "" , fmt .Errorf ("%s: %w" , errGetSpaceReference , err )
163+ }
164+
165+ if len (spaceRef ) == 0 || spaceRef [0 ].GUID == "" {
166+ return "" , fmt .Errorf ("%s: space %s not found" , errGetSpaceReference , spaceName )
167+ }
168+
169+ return spaceRef [0 ].GUID , nil
170+ }
171+
149172func (c * CFClient ) getApps (ctx context.Context , filter map [string ]string ) ([]interface {}, error ) {
173+
150174 // Get name filter
151175 name , ok := filter ["name" ]
152176 if ! ok {
153177 return nil , fmt .Errorf ("name filter is required for apps" )
154178 }
155- spaceName , ok := filter ["space" ]
156- if ! ok {
157- return nil , fmt .Errorf ("org-reference filter is required for apps" )
158- }
159179
160180 // get referenced space
161- spaceRefFilter := cfv3.SpaceListOptions {Names : cfv3.Filter {Values : []string {spaceName }}}
162- spaceRef , err := c .client .Spaces .ListAll (ctx , & spaceRefFilter )
163- kingpin .FatalIfError (err , "%s" , errGetSpaceReference )
164-
165- if spaceRef [0 ].GUID == "" {
166- kingpin .FatalIfError (fmt .Errorf ("organization %s not found" , spaceName ), "%s" , errGetOrgReference )
181+ spaceGUID , err := c .getSpaceReference (ctx , filter )
182+ if err != nil {
183+ return nil , err
167184 }
168185
186+ utils .PrintLine ("Fetching apps in space:" , spaceGUID , 30 )
169187 // define filter-option with spaceRef for query
170- opt := & cfv3.AppListOptions {SpaceGUIDs : cfv3.Filter {Values : []string {spaceRef [ 0 ]. GUID }}}
188+ opt := & cfv3.AppListOptions {SpaceGUIDs : cfv3.Filter {Values : []string {spaceGUID }}}
171189
172190 // Get apps from CF
173191 responseCollection , err := c .client .Applications .ListAll (ctx , opt )
@@ -193,22 +211,15 @@ func (c *CFClient) getRoutes(ctx context.Context, filter map[string]string) ([]i
193211 if ! ok {
194212 return nil , fmt .Errorf ("host filter is required for routes" )
195213 }
196- spaceName , ok := filter ["space" ]
197- if ! ok {
198- return nil , fmt .Errorf ("space-reference filter is required for routes" )
199- }
200214 domainName , ok := filter ["domain" ]
201215 if ! ok {
202216 return nil , fmt .Errorf ("domain-reference filter is required for routes" )
203217 }
204218
205219 // get referenced space
206- spaceRefFilter := cfv3.SpaceListOptions {Names : cfv3.Filter {Values : []string {spaceName }}}
207- spaceRef , err := c .client .Spaces .ListAll (ctx , & spaceRefFilter )
208- kingpin .FatalIfError (err , "%s" , errGetSpaceReference )
209-
210- if spaceRef [0 ].GUID == "" {
211- kingpin .FatalIfError (fmt .Errorf ("space %s not found" , spaceName ), "%s" , errGetSpaceReference )
220+ spaceGUID , err := c .getSpaceReference (ctx , filter )
221+ if err != nil {
222+ return nil , err
212223 }
213224
214225 // get referenced domain
@@ -222,7 +233,7 @@ func (c *CFClient) getRoutes(ctx context.Context, filter map[string]string) ([]i
222233
223234 // define filter-option with spaceRef for query
224235 opt := & cfv3.RouteListOptions {
225- SpaceGUIDs : cfv3.Filter {Values : []string {spaceRef [ 0 ]. GUID }},
236+ SpaceGUIDs : cfv3.Filter {Values : []string {spaceGUID }},
226237 DomainGUIDs : cfv3.Filter {Values : []string {domainRef [0 ].GUID }},
227238 }
228239
@@ -244,6 +255,84 @@ func (c *CFClient) getRoutes(ctx context.Context, filter map[string]string) ([]i
244255 return results , nil
245256}
246257
258+ func (c * CFClient ) getServiceInstances (ctx context.Context , filter map [string ]string ) ([]interface {}, error ) {
259+
260+ // Get name filter
261+ name , ok := filter ["name" ]
262+ if ! ok {
263+ return nil , fmt .Errorf ("name filter is required for service instances" )
264+ }
265+
266+ utils .PrintLine ("Fetching service instances:" , name , 30 )
267+ // get referenced space
268+ spaceGUID , err := c .getSpaceReference (ctx , filter )
269+ if err != nil {
270+ return nil , err
271+ }
272+ utils .PrintLine ("Fetching service instances in space ..." , spaceGUID , 30 )
273+
274+ // define filter-option with spaceRef for query
275+ opt := & cfv3.ServiceInstanceListOptions {SpaceGUIDs : cfv3.Filter {Values : []string {spaceGUID }}}
276+
277+ if serviceType , ok := filter ["type" ]; ok {
278+ opt .Type = serviceType
279+ }
280+
281+ // Get service instances from CF
282+ responseCollection , err := c .client .ServiceInstances .ListAll (ctx , opt )
283+ if err != nil {
284+ return nil , err
285+ }
286+
287+ utils .PrintLine ("# service instances" , strconv .Itoa (len (responseCollection )), 30 )
288+
289+ // Filter service instances by name
290+ var results []interface {}
291+ for _ , serviceInstance := range responseCollection {
292+ if utils .IsFullMatch (name , serviceInstance .Name ) {
293+ results = append (results , serviceInstance )
294+ }
295+ }
296+
297+ return results , nil
298+ }
299+
300+ func (c * CFClient ) GetServicePlan (ctx context.Context , guid string ) (* v1alpha1.ServicePlanParameters , error ) {
301+ sp , err := c .client .ServicePlans .Get (ctx , guid )
302+ if err != nil {
303+ return nil , fmt .Errorf ("failed to get service plan: %w" , err )
304+ }
305+
306+ // Get service offering details
307+ so , err := c .client .ServiceOfferings .Get (ctx , sp .Relationships .ServiceOffering .Data .GUID )
308+ if err != nil {
309+ return nil , fmt .Errorf ("failed to get service offering: %w" , err )
310+ }
311+
312+ return & v1alpha1.ServicePlanParameters {
313+ ID : & sp .GUID ,
314+ Offering : & so .Name ,
315+ Plan : & sp .Name ,
316+ }, nil
317+ }
318+
319+ func (c * CFClient ) GetServiceCredentials (ctx context.Context , guid string , serviceType string ) (* json.RawMessage , error ) {
320+ // Get credentials based on service type
321+ if serviceType == "managed" {
322+ params , err := c .client .ServiceInstances .GetManagedParameters (ctx , guid )
323+ if err != nil {
324+ return nil , fmt .Errorf ("failed to get managed service parameters: %w" , err )
325+ }
326+ return params , nil
327+ } else {
328+ creds , err := c .client .ServiceInstances .GetUserProvidedCredentials (ctx , guid )
329+ if err != nil {
330+ return nil , fmt .Errorf ("failed to get user-provided service credentials: %w" , err )
331+ }
332+ return creds , nil
333+ }
334+ }
335+
247336// CFClientAdapter implements the ClientAdapter interface
248337type CFClientAdapter struct {}
249338
0 commit comments