Not able to get all repositories through github API - go

I want to allow the users to signup using github account, and display all his/her private and public repositories. I am able to get the token from github and get the repositories (both public and private), but the only problem is that it is not returning all repositories (i.e. some repositories are not fetched).
I am using golang for server side implementation.
Using this method to get repositories.

By default all the commands that accept a ListOptions argument have a PerPage attribute. In order to get all the data, you'll have to iterate through the pages using the Page attribute until the number of results you get is less than PerPage.
In Go-ish pseudo-code, it'd look like this:
totalResults := []Result{}
for page := 0; ; page++ {
results := fetch current page
totalResults = append(totalResults, results)
if len(results) < per page {
break
}
}
You can see the ListOptions struct defined here.

As pointed out by robbrit to get all repos we have to use PerPage option, because by default only 30 repos are returned. That solved my problem.

Related

Update status in a custom Kubernetes controller in golang

I am building a Go Kubernetes operator. I have used kubebuilder to create it.
I want to store some internal details in the CRD status. I have tried :
To update the whole resource :
if err = r.Client.Update(ctx, upCRD); err != nil {
return ctrl.Result{}, client.IgnoreNotFound(err)
}
And to update only the status :
if err = r.Status().Update(ctx, upCRD); err != nil {
return reconcile.Result{}, client.IgnoreNotFound(err)
}
The status struct is defined as follows :
type HAAuditStatus struct {
ChaosStrategyCron cron.EntryID `json:"chaosStrategyCron,omitempty"`
TestStatus TestStatus `json:"testStatus,omitempty"`
MetricStatus MetricStatus `json:"metricStatus,omitempty"`
RoundRobinStrategy RoundRobinStrategy `json:"roundRobinStrategy,omitempty"`
FixedStrategy FixedStrategy `json:"fixedStrategy,omitempty"`
NextChaosDateTime int64 `json:"nextChaosDateTime,omitempty"`
Created bool `json:"created,default=false"`
}
No error is raised and the specs fields modified are actually persisted but not the status field whose values remain the default at the next reconciling step.
I have looked at the other issues on GitHub or StackOverflow but any suggestion made solved my issue and I can't figure out what is the problem. For a a bigger picture, you can refer to the repo where the operator is located.
Any suggestion is very welcomed :)
I might have found the reason why the status were not updated.
Before updating the status, I was also updating the spec fields (to give some feedback to the user on created resources).
The issue is caused by the fact that the specs updates trigger a new reconcilation, and the instruction after this update (among them the status update) were not execute.
I realized that using specs to give feedback to the user is not suitable and the events were more appropriate for this purpose.

How to limit the amount of the alias in gqlgen library Go

I'm using gqlgen package to create GraphQL server. However, I can't limit the amount of the alias. FixedComplexityLimit limits the complexity of the query. It is possible in JS community thanks to graphql-no-alias npm package. I need that kind of thing.
I want to limit the amount of the alias to prevent the batching attack. Let's try to explain by giving an example.
query {
productsByIds(productIds: "353573855") {
active {
id
path
title
}
productsByIds2: productsByIds(productIds: "353573855") {
active {
id
path
title
}
}
}
The above query should give an error. However, the below should work. This is just an example I have more complex schemas that's why the complexity limit didn't work for me.
query {
productsByIds(productIds: "353573855") {
active {
id
path
title
}
products {
active {
id
path
title
}
}
}
I'm afraid you have to come with something on your own for that. If you think the request itself or the response could become too large, you can limit it in your router config. For example, with fiber you could do:
routerConfig := fiber.Config{ReadBufferSize: maxRequestSize, WriteBufferSize: maxResponseSize};
router := fiber.New(routerConfig)
router.Post("/graphql", adaptor.HTTPHandler(gqlHandler))
If it's just really the aliases you want to prevent, you need to parse the request. You can either do so by some custom middle ware before the request gets passed to the gqlHandler (advantage: you can stop parsing the request in total in case of an alias request, disadvantage: you're basically duplicating code from a library, and it needs to be parsed again later on if you don't drop the standard gqlHandler). Or, and that's what I propose, you check the parsed request.
import gqlLib "github.com/99designs/gqlgen/graphql"
...
oCtx := gqlLib.GetOperationContext(ctx)
fragmentToSelections := getFragmentsSelectionsByName(oCtx)
selectionSet := oCtx.Operation.SelectionSet
An alias can be detected by having an Alias that differs from the Name:
file is just the query root in this example. selectionSet[0] is an unaliased request, selectionSet[1] is.

Max number of classroom id retrieved

I have aprox 520 classrooms archived in my account, if I try to select them with
var courseList = Classroom.Courses.list({"courseStates":["ARCHIVED"]}).courses;
I get only 300 of them. Is this normal?
How can I select them all? Actually I'm writing a script to delete the oldest, but if I can't retrieve them, I can't delete them.
I understand that you got so many courses that the Courses.list() response is splitted in separate pages. In that case you can very easily navigate them by using tokens. First of all, make sure that you specify the pageSize in your request. That would set the desired amount of responses per page. Please keep in mind that the server may return fewer than the specified number of results, as it declared on the docs. In case that your response got divided into pages, the response would include the nextPageToken field. Then, to obtain the rest of courses, you have to repeat your request including that nextPageToken into the pageToken property. Please don't hesitate to ask me any doubt about this approach.
Thanks a lot Jaques, I found the solution:
var parametri = {"courseStates": "ARCHIVED"};
var page = Classroom.Courses.list(parametri);
var listaClassi = page.courses;
if (page.nextPageToken !== '') {
parametri.pageToken = page.nextPageToken;
page = Classroom.Courses.list(parametri);
listaClassi = listaClassi.concat(page.courses);
}
Anyway, I didn't need to change the pageSize, nor I found any tutorial about it.

How to read from Datastore using an Ancestor query and latest golang libraries

I want to read all entities from a Datastore kind (around 6 entities/records).
I have a Datastore that is key'ed on a weird type that I am trying to understand. I can't find any uniqueness on the a key to perform a query on.
The table looks like this:
GCP Datastore representing data I want to read into my Go app
When I click on a record, it looks like this:
Key literal exposed and used from here on out to try and get the records in the Go app
``I can perform an ancestor query in the console like this:```
GCP Datastore queried using Ancestor query
Great! So now I want to retrieve this data from my Golang App? But how?
I see a lot of solutions online about using q.Get(...) // where q is a *Query struct
Any of these solutions won't work because they import google.golang.org/appengine/datastore. I understand that this is legacy and deprecated. So I want a solution that imports cloud.google.com/go/datastore.
I tried something along these lines but didn't get much luck:
First try using GetAll and query
I tried this next:
Second try attempting to use ancestor query... not ready yet
Lastly I tried to get a single record directly:
Lastly I tried to get the record directly
In all cases, my err is not nil and the dts that should be populated from datastore query is also nil.
Any guidance to help me understand how to query on this key type? Am I missing something fundamental with the way this table is key'ed and queried?
Thank you
Then I tried this:
It seems you are just missing your Namespace
// Merchant Struct
type MerchantDetails struct {
MEID string
LinkTo *datastore.Key
Title string
}
// Struct array to store in
var tokens []MerchantDetails
// Ancestor Key to filter by
parentKey := datastore.NameKey("A1_1113", "activate", nil)
parentKey.Namespace = "Devs1"
// The call using the new datastore UI. Basically query.Run(), but datastore.GetAll()
keys, err := helpers.DatastoreClient.GetAll(
helpers.Ctx,
datastore.NewQuery("A1_1112").Ancestor(parentKey).Namespace("Devs1"),
&tokens,
)
if err != nil {
return "", err
}
// Print all name/id from the found values
fmt.Printf("keys: %v", keys)

How to search for a specific value in Firebase using Golang?

I am using Golang and Firego for connecting to Firebase. I am trying to search an admin with Email: john#gmail.com. The following is my Database Structure
For this I have tried:
dB.Child("CompanyAdmins").Child("Info").OrderBy("Email").EqualTo("john#gmail.com").Value(&result)
but it does not produce expected result. How can I do this?
While #dev.bmax has the problem identified correctly, the solution is simpler. You can specify the path of a property to order on:
dB.Child("CompanyAdmins")
.OrderBy("Info/Email")
.EqualTo("john#gmail.com")
.Value(&result)
Update (2017-02-10):
Full code I just tried:
f := firego.New("https://stackoverflow.firebaseio.com", nil)
var result map[string]interface{}
if err := f.Child("42134844/CompanyAdmins").OrderBy("Info/Email").EqualTo("john#gmail.com").Value(&result); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", result)
This prints:
map[-K111111:map[Info:map[Email:john#gmail.com]]]
Which is the exact place where I put the data.
Update 20170213:
This is the index I have defined:
"CompanyAdmins": {
".indexOn": "Info/Email"
}
If this doesn't work for you, please provide a similarly complete snippet that I can test.
Can you put Info data directly into CompanyAdmins structure? This way, your query will work.
CompanyAdmins
-id
-Email: "johndon#gmail.com"
-Settings:
- fields
The problem with your query, is that Info is not a direct child of CompanyAdmins.
You could use the email as the key instead of an auto-generated one when you insert values. That way, you can access the admin directly:
dB.Child("CompanyAdmins").Child("john#gmail.com").Child("Info")
Otherwise, you need to restructure the database. Your order-by field (email) should be one level higher, like Rodrigo Vinicius suggests. Then, your query will change to:
dB.Child("CompanyAdmins").OrderBy("Email").EqualTo("john#gmail.com")

Resources