Crie notas e ocorrências personalizadas

Pode optar por fornecer os seus próprios metadados à análise de artefactos para satisfazer uma necessidade empresarial específica. Por exemplo, uma organização que fornece gestão de segurança para os contentores Docker dos respetivos clientes pode usar a análise de artefactos para armazenar e obter metadados relacionados com a segurança dessas imagens.

Os passos seguintes mostram como fornecer metadados de atestação para as suas imagens através da API Artifact Analysis. Pode usar as mesmas instruções para armazenar e obter qualquer tipo de metadados que a análise de artefactos suporta.

Antes de começar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Enable the Container Analysis API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  4. Install the Google Cloud CLI.

  5. Se estiver a usar um fornecedor de identidade (IdP) externo, tem primeiro de iniciar sessão na CLI gcloud com a sua identidade federada.

  6. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  7. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  8. Enable the Container Analysis API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  9. Install the Google Cloud CLI.

  10. Se estiver a usar um fornecedor de identidade (IdP) externo, tem primeiro de iniciar sessão na CLI gcloud com a sua identidade federada.

  11. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  12. Saiba como configurar o controlo de acesso para os metadados no seu projeto. Ignore este passo se apenas consumir metadados de ocorrências criadas pela análise de artefactos.
  13. Crie notas e ocorrências para projetos

    Esta secção explica como pode criar notas e ocorrências. Para este exemplo, vai usar o tipo ATTESTATION.

    Enquanto fornecedor, cria uma nota no seu projeto para cada atestação e cria uma ocorrência no projeto do cliente para uma ocorrência dessa atestação.

    Criar notas

    Use os passos seguintes para criar uma nota e atribuir-lhe um ID.

    API

    1. Crie um ficheiro com o nome note.json com a descrição e os detalhes da atestação. O código seguinte mostra um exemplo de ficheiro note.json:

      {
        "shortDescription": "A brief Description of the note",
        "longDescription": "A longer description of the note",
        "kind": "ATTESTATION",
        "attestation": {
          "hint": {
            "humanReadableName": "my-attestation-authority"
          }
        }
      }
      

      Consulte a documentação da API Notes para mais informações sobre a representação JSON das notas.

    2. Execute o seguinte comando curl para criar uma nota:

      curl -v -H "Content-Type: application/json" -H \
        "Authorization: Bearer $(gcloud auth print-access-token)" \
        https://containeranalysis.googleapis.com/v1/projects/PROVIDER_PROJECT_ID/notes?note_id=NOTE_ID -d @note.json
      

      Onde:

      • PROVIDER_PROJECT_ID é o ID do seu projeto.
      • NOTE_ID especifica um identificador para a sua nota. Use uma string com um comprimento máximo de 100 carateres.

    Java

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API Java de análise de artefactos.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
    import io.grafeas.v1.GrafeasClient;
    import io.grafeas.v1.Note;
    import io.grafeas.v1.ProjectName;
    import io.grafeas.v1.Version;
    import io.grafeas.v1.AttestationNote;
    import java.io.IOException;
    import java.lang.InterruptedException;
    
    public class CreateNote {
    
      // Creates and returns a new Note
      public static Note createNote(String noteId, String projectId)
          throws IOException, InterruptedException {
        // String noteId = "my-note";
        // String projectId = "my-project-id";
        final String projectName = ProjectName.format(projectId);
    
        Note newNote =
            Note.newBuilder()
                // Associate the Note with the metadata type
                // https://cloud.google.com/container-registry/docs/container-analysis#supported_metadata_types
                // Here, we use the type "attestation"
                .setAttestation(
                    AttestationNote.newBuilder()
                        .setHint(
                            AttestationNote.Hint.newBuilder()
                                .setHumanReadableName("my-attestation-authority")))
                .build();
    
        // Initialize client that will be used to send requests. After completing all of your requests,
        // call the "close" method on the client to safely clean up any remaining background resources.
        GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
        Note result = client.createNote(projectName, noteId, newNote);
        return result;
      }
    }
    

    Ir

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API Go Artifact Analysis.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    
    import (
      "context"
      "fmt"
    
      containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
      grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
    )
    
    // createNote creates and returns a new attestation Note.
    func createNote(noteID, projectID string) (*grafeaspb.Note, error) {
      ctx := context.Background()
      client, err := containeranalysis.NewClient(ctx)
      if err != nil {
        return nil, fmt.Errorf("NewClient: %w", err)
      }
      defer client.Close()
    
      projectName := fmt.Sprintf("projects/%s", projectID)
    
      req := &grafeaspb.CreateNoteRequest{
        Parent: projectName,
        NoteId: noteID,
        Note: &grafeaspb.Note{
          Type: &grafeaspb.Note_Attestation{
            Attestation: &grafeaspb.AttestationNote{
              Hint: &grafeaspb.AttestationNote_Hint{
                HumanReadableName: "my-attestation-authority",
              },
            },
          },
        },
      }
    
      return client.GetGrafeasClient().CreateNote(ctx, req)
    }
    

    Node.js

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API Node.js de análise de artefactos.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    /**
    * TODO(developer): Uncomment these variables before running the sample
    */
    // const projectId = 'your-project-id', // Your Google Cloud Project ID
    // const noteId = 'my-note-id' // Id of the note
    
    // Import the library and create a client
    const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
    const client = new ContainerAnalysisClient();
    
    // Construct request
    // Associate the Note with a metadata type
    // https://cloud.google.com/container-registry/docs/container-analysis#supported_metadata_types
    // Here, we use the type "attestation"
    const formattedParent = client.getGrafeasClient().projectPath(projectId);
    
    // Creates and returns a new Note
    const [note] = await client.getGrafeasClient().createNote({
      parent: formattedParent,
      noteId: noteId,
      note: {
        attestation: {
          hint: {
            humanReadableName: 'my-attestation-authority',
          },
        },
      },
    });
    
    console.log(`Note ${note.name} created.`);
    

    Ruby

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API Ruby de análise de artefactos.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    # note_id = "A user-specified identifier for the note"
    # project_id = "Your Google Cloud project ID"
    
    require "google/cloud/container_analysis"
    
    # Initialize the client
    client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client
    
    parent = client.project_path project: project_id
    note = {
      attestation: {
        hint: {
          human_readable_name: "attestation-authority"
        }
      }
    }
    response = client.create_note parent: parent, note_id: note_id, note: note
    puts response.name
    

    Python

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API Python de análise de artefactos.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    from google.cloud.devtools import containeranalysis_v1
    from grafeas.grafeas_v1 import types, Version
    
    def create_note(note_id: str, project_id: str) -> types.grafeas.Note:
        """Creates and returns a new attestation note."""
        # note_id = 'my-note'
        # project_id = 'my-gcp-project'
    
        client = containeranalysis_v1.ContainerAnalysisClient()
        grafeas_client = client.get_grafeas_client()
        project_name = f"projects/{project_id}"
        note = {
          "attestation": {
            "hint": {
              "human_readable_name": "attestation-authority",
            }
          }
        }
        response = grafeas_client.create_note(
            parent=project_name, note_id=note_id, note=note
        )
        return response
    

    Crie ocorrências para as notas

    Para criar ocorrências para uma nota:

    API

    1. Crie um ficheiro com o nome occurrence.json com a descrição e os detalhes da atestação. O código seguinte mostra um exemplo de ficheiro occurrence.json:

      {
        "resourceUri": "your-resource-uri-here",
        "noteName": "projects/your-note-project/notes/your-note-id",
        "kind": "ATTESTATION",
        "attestation": {
          "serializedPayload": "eW91ci1wYXlsb2FkLWhlcmU=",
          "signatures": [
            {
              "publicKeyId": "your-key-id-here",
              "signature": "eW91ci1zaWduYXR1cmUtaGVyZQ=="
            }
          ]
        }
      }
      

      Consulte a documentação da API Notes para mais informações sobre a representação JSON das notas.

    2. Execute o seguinte comando curl para criar uma ocorrência:

      curl -v -H "Content-Type: application/json" -H \
        "Authorization: Bearer $(gcloud auth print-access-token)" \
        https://containeranalysis.googleapis.com/v1/projects/PROVIDER_PROJECT_ID/occurrences/ -d @occurrence.json
      

      Onde:

      • PROVIDER_PROJECT_ID é o ID do seu projeto.
      • NOTE_ID especifica um identificador para a sua nota. Use uma string com um comprimento máximo de 100 carateres.

    Java

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API Java de análise de artefactos.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
    import com.google.protobuf.ByteString;
    import io.grafeas.v1.AttestationOccurrence;
    import io.grafeas.v1.GrafeasClient;
    import io.grafeas.v1.NoteName;
    import io.grafeas.v1.Occurrence;
    import io.grafeas.v1.ProjectName;
    import io.grafeas.v1.Signature;
    import java.io.IOException;
    
    public class CreateOccurrence {
      // Creates and returns a new attestation Occurrence associated with an existing Note
      public static Occurrence createOccurrence(
          String resourceUrl, String noteId, String occProjectId, String noteProjectId)
          throws IOException {
        // String resourceUrl = "https://gcr.io/project/image@sha256:123";
        // String noteId = "my-note";
        // String occProjectId = "my-project-id";
        // String noteProjectId = "my-project-id";
        final NoteName noteName = NoteName.of(noteProjectId, noteId);
        final String occProjectName = ProjectName.format(occProjectId);
    
        Occurrence newOcc =
            Occurrence.newBuilder()
                .setNoteName(noteName.toString())
                .setResourceUri(resourceUrl)
                .setAttestation(
                    AttestationOccurrence.newBuilder()
                        .setSerializedPayload(ByteString.copyFrom("your-payload-here", "UTF-8"))
                        .addSignatures(
                            Signature.newBuilder()
                                .setPublicKeyId("your-key-id-here")
                                .setSignature(ByteString.copyFrom("your-signature-here", "UTF-8"))))
                .build();
    
        // Initialize client that will be used to send requests. After completing all of your requests,
        // call the "close" method on the client to safely clean up any remaining background
        // resources.
        GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
        Occurrence result = client.createOccurrence(occProjectName, newOcc);
        return result;
      }
    }
    

    Ir

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API Go Artifact Analysis.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    import (
      "context"
      "fmt"
    
      containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
      grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
    )
    
    // createsOccurrence creates and returns a new Occurrence of a previously created attestation note.
      // Use this style of URL when you use Google Artifact Registry.
      // resourceURL := "https://LOCATION-docker.pkg.dev/my-project/my-repo/my-image"
      // noteID := "my-note"
      ctx := context.Background()
      client, err := containeranalysis.NewClient(ctx)
      if err != nil {
        return nil, fmt.Errorf("NewClient: %w", err)
      }
      defer client.Close()
    
      req := &grafeaspb.CreateOccurrenceRequest{
        Parent: fmt.Sprintf("projects/%s", occProjectID),
        Occurrence: &grafeaspb.Occurrence{
          NoteName: fmt.Sprintf("projects/%s/notes/%s", noteProjectID, noteID),
          // Attach the occurrence to the associated resource uri.
          ResourceUri: resourceURL,
          // Details about the attestation can be added here.
          Details: &grafeaspb.Occurrence_Attestation{
            Attestation: &grafeaspb.AttestationOccurrence{
              SerializedPayload: []byte("..."),
              Signatures: []*grafeaspb.Signature{
                {
                  PublicKeyId: "...",
                  Signature:   []byte("..."),
                },
              },
            },
          },
        },
      }
      return client.GetGrafeasClient().CreateOccurrence(ctx, req)
    }
    

    Node.js

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API Node.js de análise de artefactos.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    /**
     * TODO(developer): Uncomment these variables before running the sample
     */
    // const noteProjectId = 'your-project-id', // Your Google Cloud Project ID
    // const noteId = 'my-note-id', // Id of the note
    // const occurrenceProjectId = 'your-project-id', // The Google Cloud Project ID of the occurrence
    // If you are using Google Artifact Registry
    // const imageUrl = 'https://LOCATION-docker.pkg.dev/my-project/my-repo/my-image:123' // Image to attach metadata to
    
    // Import the library and create a client
    const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
    const client = new ContainerAnalysisClient();
    
    // Construct request
    const formattedParent = client
    .getGrafeasClient()
    .projectPath(occurrenceProjectId);
    const formattedNote = client
    .getGrafeasClient()
    .notePath(noteProjectId, noteId);
    
    // Creates and returns a new Occurrence associated with an existing Note
    const [occurrence] = await client.getGrafeasClient().createOccurrence({
    parent: formattedParent,
    occurrence: {
      noteName: formattedNote,
      resourceUri: imageUrl,
      attestation: {
        serializedPayload: Buffer.from('your-payload-here').toString('base64'),
        signatures: [
          {
            publicKeyId: 'your-key-id-here',
            signature: Buffer.from('your-signature-here').toString('base64'),
          },
        ],
      },
    },
    });
    console.log(`Occurrence created ${occurrence.name}.`);
    return occurrence;
    

    Ruby

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API Ruby de análise de artefactos.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    # note_id    = "A user-specified identifier for the note"
    # project_id = "Your Google Cloud project ID"
    # note_project = "The project that contains the note"
    # occurrence_project = "The project that contains the occurrence"
    
    require "google/cloud/container_analysis"
    require "base64"
    
    # Initialize the client
    client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client
    note_path = client.note_path project: note_project, note: note_id
    project_path = client.project_path project: occurrence_project
    
    occurrence = {
      note_name:    note_path,
      resource_uri: resource_url,
      attestation:  {
        serialized_payload: Base64.encode64("your-payload-here"),
        signatures:         [
          {
            public_key_id: "your-key-id-here",
            signature:     Base64.encode64("your-signature-here")
          }
        ]
      }
    }
    
    response = client.create_occurrence parent: project_path, occurrence: occurrence
    puts response.name
    

    Python

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API Python de análise de artefactos.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    import base64
    from google.cloud.devtools import containeranalysis_v1
    from grafeas.grafeas_v1 import types
    
    def create_occurrence(
        resource_url: str, note_id: str, occurrence_project: str, note_project: str
    ) -> types.grafeas.Occurrence:
        """Creates and returns a new occurrence of a previously
        created attestation note."""
        # note_id = 'my-note'
        # project_id = 'my-gcp-project'
    
        client = containeranalysis_v1.ContainerAnalysisClient()
        grafeas_client = client.get_grafeas_client()
        formatted_note = f"projects/{note_project}/notes/{note_id}"
        formatted_project = f"projects/{occurrence_project}"
    
        occurrence = {
            "note_name": formatted_note,
            "resource_uri": resource_url,
            "attestation": {
                "serialized_payload": base64.b64encode(b"your-payload-here").decode("utf-8"),
                "signatures": [
                    {
                        "public_key_id": "your-key-id-here",
                        "signature": base64.b64encode(b"your-signature-here").decode("utf-8"),
                    }
                ],
            },
        }
    
        return grafeas_client.create_occurrence(
            parent=formatted_project, occurrence=occurrence
        )
    

    Ver todas as ocorrências de uma nota específica

    Pode ver todas as ocorrências de uma atestação específica nos projetos do seu cliente através do notes.occurrences.list().

    API

    Para apresentar uma lista de todas as ocorrências de uma nota, envie um pedido GET da seguinte forma:

    GET https://containeranalysis.googleapis.com/v1/projects/PROJECT_ID/notes/NOTE_ID/occurrences
    

    Consulte o ponto final da API projects.notes.occurrences.list para ver os detalhes completos.

    Java

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API JavaArtifact Analysis.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    import static java.lang.Thread.sleep;
    
    import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
    import io.grafeas.v1.GrafeasClient;
    import io.grafeas.v1.ListNoteOccurrencesRequest;
    import io.grafeas.v1.NoteName;
    import io.grafeas.v1.Occurrence;
    import java.io.IOException;
    import java.lang.InterruptedException;
    
    public class OccurrencesForNote {  
      // Retrieves all the Occurrences associated with a specified Note
      // Here, all Occurrences are printed and counted
      public static int getOccurrencesForNote(String noteId, String projectId) 
          throws IOException, InterruptedException {
        // String noteId = "my-note";
        // String projectId = "my-project-id";
        final NoteName noteName = NoteName.of(projectId, noteId);
    
        ListNoteOccurrencesRequest request = ListNoteOccurrencesRequest.newBuilder()
                                                                       .setName(noteName.toString())
                                                                       .build();
    
        // Initialize client that will be used to send requests. After completing all of your requests, 
        // call the "close" method on the client to safely clean up any remaining background resources.
        GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
        int i = 0;
        for (Occurrence o : client.listNoteOccurrences(request).iterateAll()) {
          // Write custom code to process each Occurrence here
          System.out.println(o.getName());
          i = i + 1;
        }
        return i;
      }
    }

    Go

    Para saber como instalar e usar a biblioteca de cliente para a análise de artefactos, consulte o artigo Bibliotecas de cliente da análise de artefactos. Para mais informações, consulte a documentação de referência da API GoArtifact Analysis.

    Para se autenticar no Artifact Analysis, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

    
    import (
    	"context"
    	"fmt"
    	"io"
    
    	containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
    	"google.golang.org/api/iterator"
    	grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
    )
    
    // getOccurrencesForNote retrieves all the Occurrences associated with a specified Note.
    // Here, all Occurrences are printed and counted.
    func getOccurrencesForNote(w io.Writer, noteID, projectID string) (int, error) {
    	// noteID := fmt.Sprintf("my-note")
    	ctx := context.Background()
    	client, err := containeranalysis.NewClient(ctx)
    	if err != nil {
    		return -1, fmt.Errorf("NewClient: %w", err)
    	}
    	defer client.Close()
    
    	req := &grafeaspb.ListNoteOccurrencesRequest{
    		Name: fmt.Sprintf("projects/%s/notes/%s", projectID, noteID),
    	}
    	it := client.GetGrafeasClient().ListNoteOccurrences(ctx, req)
    	count := 0
    	for {
    		occ, err := it.Next()
    		if err == iterator.Done {
    			break
    		}
    		if err != nil {
    			return -1, fmt.Errorf("occurrence iteration error: %w", err)
    		}
    		// Write custom code to process each Occurrence here.
    		fmt.Fprintln(w, occ)
    		count = count + 1
    	}
    	return count, nil
    }
    

    Node.js