Git Product home page Git Product logo

opcua's People

Contributors

alexbrdn avatar bamchoh avatar bitomaxsp avatar ceh avatar crowdhailer avatar dhia-gharsallaoui avatar diericd avatar dvrkps avatar dwhutchison avatar goodspeed1986 avatar gstvg avatar hotafrika avatar jackchenjc avatar jeremytheocharis avatar kmpm avatar kung-foo avatar larsstegman avatar lcw2 avatar maddin-619 avatar magiconair avatar marcus-orchard avatar mmikalsen avatar mvandergrift avatar sdghchj avatar siscia avatar sruehl avatar tomhollingworth avatar vereecw avatar wmnsk avatar zemirco avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opcua's Issues

Method to retrieve Identifier value in NodeID

When handling each type of NodeID, the main concern of the user is to retrieve values in Identifier field.
So, I'm considering to implement Value() or Payload() method on each NodeID, which makes the NodeID interface to return the value without asserting.

Design in my mind

  • Modify interface
type NodeID interface {
	Serialize() ([]byte, error)
	SerializeTo([]byte) error
	DecodeFromBytes([]byte) error
	Len() int
	String() string
	EncodingMaskValue() uint8
	SetURIFlag()
	SetIndexFlag()
	Value() ([]byte, error) // Add this line
}
  • Basic method
func (n *NumericNodeID) Value() ([]byte, error) {
	if n == nil {
		return nil, errors.NewErrReceiverNil(n)
	}

	// return identifier as it is
	return n.Identifier, nil
}
  • Special case for GUIDNodeID
func (g *GUIDNodeID) Value() ([]byte, error) {
	if n == nil {
		return nil, errors.NewErrReceiverNil(g)
	}

	// return serialized GUID instead of GUID structure
	return n.GUID.Serialize()
}

Implement automated Session handling

Session creation and activation should be done automatically with smallest user inputs.

  • Implement Session which implements net.Conn interface
  • ...

Change ExtensionObject to ExtensibleParameter?

In specification parameters like UserIdentityToken is described as ExtensibleParameter, not ExtensionParameter, while Wireshark calls it ExtensionObject.

  • Investigate which one to be used.
  • Fix if needed.

Fix array size encoding

With current implementation, ArraySize will be encoded as 0xffffffff when the array contains nothing.
This should be corrected as 0x00000000.

Example: Array of String (should be applied to some other constructors)

// NewStringArray creates a new StringArray from multiple strings.
func NewStringArray(strs []string) *StringArray {
	if strs == nil {
		s := &StringArray{
			ArraySize: -1, // <= This should be 0.
		}
		return s
	}

	s := &StringArray{
		ArraySize: int32(len(strs)),
	}
	for _, ss := range strs {
		s.Strings = append(s.Strings, NewString(ss))
	}

	return s
}

encoder should be smart about empty structs

The OPC/UA binary protocol has no mechanism to express a nil struct. This means that all struct fields at least represent a Go zero value for that struct. Additionally, the current code generator creates struct fields as pointers which has the effect that all struct fields need to be initialized with at least an empty value.

Here is an example from the ua/write_response_test.go.

Struct: &WriteResponse{
	ResponseHeader: &ResponseHeader{
		Timestamp:     time.Date(2018, time.August, 10, 23, 0, 0, 0, time.UTC),
		RequestHandle: 1,
		ServiceDiagnostics: &DiagnosticInfo{},
		StringTable:        []string{},
		AdditionalHeader:   NewExtensionObject(nil),
	},
	Results: []StatusCode{StatusOK},
},

This behavior was also the cause for a discrepancy in #162 where a field of the session configuration had not been initialized.

One fix is to make the encoder smart about nil values. That has the effect that tests can no longer use the same structs for encoding and decoding since a nil silently turns into an empty struct.

A better approach might be not to generate struct fields as pointers since they cannot be nil anyway. Then the codec just works.

Add contributing guidelines

For those who is interested in contribution, we need to provide guideline.

  • Consider what it should be like
  • Write docs in CONTRIBUTING.md
    • (Optional) Add ISSUE_TEMPLATE.md
    • (Optional) Add PULL_REQUEST_TEMPLATE.md
  • ...

Discussion on crypto support

Creating this issue for a place for discussion outside of a PR.

While trying to implement the crypto functions for the server path, I noticed a few functions which didn't work for receiving messages. Primarily, the recv() and SendAsync() functions within the uasc package were tailored for sending client messages and not capable of receiving messages. The majority of the code is fine and the problems weren't major, but they do need some adjustment. For example, the SendAsync method would panic while trying to copy the reqHdr field into a ResponseHeader and the recv method could only handle messages with existing handlers (which are tied to client-generated requestIDs).

I'm preparing a PR for three things:

  1. Generalize the above uasc functions to allow for processing both 'Request' and 'Response' types.
  2. Create an initial server application layer to receive and process unsolicited messages.
  3. Incorporate the crypto functions into the transport layer
    I'm working on all three simultaneously but if I can extract parts of each, I'll try publish them individually.

Within the server logic I'm working on a concept of a 'Channel Broker' to manage multiple secure channels on one listener. With this, I'm hoping to have a method of accepting connections, creating secure channels, and handling requests from multiple connections as well as slightly decoupling the secure channel from the uacp.Conn. This is because clients are allowed to reconnect to a server provided the secure channel hasn't expired so this should allow for a means to 'reattach' a new Conn to an existing secure channel. Having a system monitoring all active secure channels will also allow for a means to prune expired connections.

I anticipate client logic remaining the same as it is now; i.e. the application controlling the creation and use of SecureChannels. One thing I'm aware of, but unsure exactly how to implement it at this time, is that clients will also need a way to reconnect to a server utilizing an existing SecureChannel if the uacp.Conn is broken. I don't anticipate this being too difficult (try to send, fail, close the uacp.Conn, open a new one, replace the old conn reference with the new one, continue on). Also need to check the spec to see if the full HEL/ACK sequence needs to be repeated in this case.

#156 was a proof of concept that the crypo functions themselves are functional, but will need more work to allow for both sending and receiving messages, decent secret management, etc. Now that I've looked closer at what it'll take to implement the server component of the logic, I should be able to clean up that sequencing.

Comments are welcome; when I have things cleaned up a bit I'll push a WIP branch for review.

Code Generation

Hi @wmnsk, I had started working on a pure go opcua implementation in April but didn't make much headway until recently but you've beaten me to the punch :)

My code is roughly in the same state (encoder, decoder, uacp, session, ...) but I think having a larger and active community is more important and your project has gained some good traction. I have some experience from that with my own open-source projects.

The one big thing I can contribute is a code generator for all OPC/UA service objects and array types and I'm also thinking of writing a reflection based Encoder/Decoder to reduce the boilerplate even further.

The generated code looks like the one below and also generates all length encoded Array variants of objects like []*ReadValueId.

Would you be interested in this? If yes, then we can discuss what the interfaces should look like since the generated code isn't a drop-in replacement for the current structures. I'll attach a PR with the code generator so that you can have a look.

package service

import (
	"bytes"

	ua "github.com/northvolt/go-opcua/datatypes"
)

type CreateSubscriptionRequest struct {
	RequestHeader               *RequestHeader
	RequestedPublishingInterval float64
	RequestedLifetimeCount      uint32
	RequestedMaxKeepAliveCount  uint32
	MaxNotificationsPerPublish  uint32
	PublishingEnabled           bool
	Priority                    uint8
}

func NewCreateSubscriptionRequest() *CreateSubscriptionRequest {
	return &CreateSubscriptionRequest{
		RequestHeader: NewRequestHeader(),
	}
}

func (m *CreateSubscriptionRequest) ID() uint16 {
	return 787
}

func (m *CreateSubscriptionRequest) GetName() string {
	return "CreateSubscriptionRequest"
}

func (m *CreateSubscriptionRequest) Read(b *bytes.Buffer) error {
	var err error
	if m.RequestHeader, err = ReadRequestHeader(b); err != nil {
		return err
	}
	if m.RequestedPublishingInterval, err = ua.ReadDouble(b); err != nil {
		return err
	}
	if m.RequestedLifetimeCount, err = ua.ReadUInt32(b); err != nil {
		return err
	}
	if m.RequestedMaxKeepAliveCount, err = ua.ReadUInt32(b); err != nil {
		return err
	}
	if m.MaxNotificationsPerPublish, err = ua.ReadUInt32(b); err != nil {
		return err
	}
	if m.PublishingEnabled, err = ua.ReadBoolean(b); err != nil {
		return err
	}
	if m.Priority, err = ua.ReadByte(b); err != nil {
		return err
	}
	return nil
}

func (m *CreateSubscriptionRequest) Write(b *bytes.Buffer) error {
	if err := WriteRequestHeader(b, m.RequestHeader); err != nil {
		return err
	}
	if err := ua.WriteDouble(b, m.RequestedPublishingInterval); err != nil {
		return err
	}
	if err := ua.WriteUInt32(b, m.RequestedLifetimeCount); err != nil {
		return err
	}
	if err := ua.WriteUInt32(b, m.RequestedMaxKeepAliveCount); err != nil {
		return err
	}
	if err := ua.WriteUInt32(b, m.MaxNotificationsPerPublish); err != nil {
		return err
	}
	if err := ua.WriteBoolean(b, m.PublishingEnabled); err != nil {
		return err
	}
	if err := ua.WriteByte(b, m.Priority); err != nil {
		return err
	}
	return nil
}

func ReadCreateSubscriptionRequest(b *bytes.Buffer) (*CreateSubscriptionRequest, error) {
	m := new(CreateSubscriptionRequest)
	if err := m.Read(b); err != nil {
		return nil, err
	}
	return m, nil
}

func WriteCreateSubscriptionRequest(b *bytes.Buffer, m *CreateSubscriptionRequest) error {
	return m.Write(b)
}
package service

import (
	"bytes"

	ua "github.com/northvolt/go-opcua/datatypes"
)

type ReadValueIdArray []*ReadValueId

func (m ReadValueIdArray) GetName() string {
	return "ReadValueIdArray"
}

func ReadReadValueIdArray(b *bytes.Buffer) ([]*ReadValueId, error) {
	n, err := ua.ReadUInt32(b)
	if err != nil {
		return nil, err
	}
	if n == ua.NilValue {
		return nil, nil
	}
	m := make([]*ReadValueId, n)
	for i := uint32(0); i < n; i++ {
		if m[i], err = ReadReadValueId(b); err != nil {
			return nil, err
		}
	}
	return m, nil
}

func WriteReadValueIdArray(b *bytes.Buffer, m []*ReadValueId) error {
	if m == nil {
		return ua.WriteUInt32(b, ua.NilValue)
	}
	if err := ua.WriteUInt32(b, uint32(len(m))); err != nil {
		return err
	}
	for i := range m {
		if err := WriteReadValueId(b, m[i]); err != nil {
			return err
		}
	}
	return nil
}

Clarify supported features

I cannot understand - is x509 Authentication supported or not?
It seems to be presented in code
https://github.com/wmnsk/gopcua/blob/72c87ce6fabe6993089b948be572e56fe94670c5/datatypes/user-identity-token.go#L253
and even tested, but supported features do not mention it as supported.
So I'm confused - was it supported not fully or it's just not working code or it's just a documentation issue?

If it's the last one I think other features should be checked too (maybe more of them supported already).
Thanks!

Move datatypes in services directory to datatypes directory

Currently some of the (non-primitive) datatypes are in services directory but they should actually be in datatypes.
This issue is to track the problem. At some point of implementation before v1.0 release, I'll work on moving them and revise some codes.

ReadResponse service

Hello,
question regards to #130 (comment)

Please could you help me with clarifying "Retrieve values in ReadResponse from server"
Did you mean, getting data from services.DecodeReadResponse(buf) and then getting from the struct of ReadResponse.Result?
I did session.Read() and variant EncodingMask shows the right type from server. But other parameters are &{10 <nil> <nil> <nil> []}

Development timeline

Hi gopcua team,

I really like your implementation in this package.
I would also like to use the browse services and I also need support for some more datatypes of the variant.
I regularly run into this error while decoding the ReadResponse message: cannot decode as uint8: got undefined type

Can you share your timeline? Are there any plans to complete the list of services and available datatypes?

Thanks
Felix

Server Support

I've pushed a WIP branch for the first kick at a server implementation. The focus on this initial code is to show the uacp package changes that need to occur to support listening for unsolicited messages and how that integrates into both the client and the server code. I anticipate these changes being the first to be merged, then the server code can follow once it's fleshed out.
The primary difference is that I moved the goroutine read loop out of the uasc package and into each of the client and server packages. The uasc package still deals with decoding/decrypting the messages, but returns the service up to the application layer. The exception to this are the Open and Close SecureChannel requests; those are dealt with directly in the uasc package without notifying the client/server.

The server implementation has preliminary support for opening and closing secure channels, auto-builds endpoints, and opening/closing/activating sessions. Authorization has config for the purpose of endpoint generation, but is otherwise not implemented yet. The session management is still in a very early state and should be normalized with the client implementation (they're currently totally separate). Other services are just placeholders for now. To properly implement further services, the server needs to implement an address space, which is what I've started looking into next.

Change parameters in Constructors

Parameters in constructors in each Service should be given as a defined types instead of respective values in the types.

e.g., Pass SignatureData instead of alg and sig in CreateSession.

Cleanup tests in services

Now the tests for each service in service_test.go is becoming too big. Need to split tests for each service and write more efficient tests.

  • OpenSecureChannelRequest
  • OpenSecureChannelResponse
  • CloseSecureChannelRequest
  • CloseSecureChannelResponse
  • GetEndpointsRequest
  • GetEndpointsResponse
  • CreateSessionRequest
  • CreateSessionResponse
  • ActivateSessionRequest
  • ActivateSessionResponse
  • CloseSessionRequest
  • CloseSessionResponse
  • ReadRequest

SecureChannel 'monitor' goroutine panics after calling SecureChannel.Close()

I've run across an issue when trying to close and create another SecureChannel inside a client. After I call Close() on the first instance of a SecureChannel, the program quickly panics due to a nil pointer deference inside func (s *SecureChannel) monitor(ctx context.Context).

I think the issue is this goroutine stays blocked on
n, err := s.lowerConn.Read(s.rcvBuf)
so it never sees that the context finishes and returns cleanly. Inside the call to close, s.lowerConn gets assigned to nil, resulting in the panic.

Simply commenting out the lowerConn nil assignment in SecureChannel.close() stops this, but I haven't looked to see if there are other impacts of doing so.

Add tests for connection-related funcs

Currently no tests implemented for networking feature which communicates with other OPC UA entity.
Those funcs should not be left untested, so I need to find the way to test it in simple and CI-friendly manner.

Add ApplicationInstanceCertificate

Currently certificates are handled as []byte, but it should actually be ApplicationInstanceCertificate.
Need to add ApplicationInstanceCertificate as described in Part4, 7.2.

GopherCon 2018: Matt Layher - Implementing a Network Protocol in Go

This is a great talk https://www.youtube.com/watch?v=pUaFW98V1Sc. The topic is very similar to what we're building. He even talks about go-fuzz.

One thing that came to mind. Our interface names are Decode and Serialize. He's using Marshal and Unmarshal like the json package https://golang.org/pkg/encoding/json/ and the proto package https://godoc.org/github.com/golang/protobuf/proto.

Therefore I'd like to propose changing our interface before releasing version 1.

Open the Wiki

Hey,

I tried adding some stuff to the wiki. Looks like it's not activated or I'm not allowed to use it. Could you change that?

Today I experimented with gopcua in the browser. I have a working example compiling it to webassembly and decoding raw messages in the browser.

The idea is to use gopcua in the browser and communicate with OPC UA servers that support websockets.

Change Request/ResponseHeader handling in constructors of service

In the current implementation, params inside RequestHeader in each service is given respectively, but it should be given with *RequestHeader to be more flexible and consice in handling services with constructor.

For example,

func NewActivateSessionRequest(ts time.Time, authToken datatypes.NodeID, handle, diag, timeout uint32, auditID string, sig *SignatureData, certs []*SignedSoftwareCertificate, locales []string, userToken *datatypes.ExtensionObject, tokenSig *SignatureData) *ActivateSessionRequest {

should be;

func NewActivateSessionRequest(reqHeader *RequestHeader, sig *SignatureData, certs []*SignedSoftwareCertificate, locales []string, userToken *datatypes.ExtensionObject, tokenSig *SignatureData) *ActivateSessionRequest {

Fix AuthToken handling

In OPC UA Session, client should set AuthenticationToken told by server, and the type of data varies within NodeId.
In current implementation it is hard-coded in some fixed types like FourByteNodeID. It should be NodeID interface to be able to set any type of NodeId given from server.

RequestedSessionTimeout not set in func (c *Client) CreateSession

I was tring to connect to an Siemens S7, using the datetime example I was unable to create a session..

the error returned was StatusBadSessionIDInvalid.
so logging the tcp packets with wireshark and matching the results with a working client I noticed that the message CreateSessionRequest has a
opcua.RequestedSessionTimeout = 0
so the S7 replied with
aopcua.RevisedSessionTimeout=1

when at next step we call ActivateSession the session is already expired.

in the source code client.go I noticed that in
func (c *Client) CreateSession the RequestedSessionTimeout of the struct ua.CreateSessionRequest is not set so it has 0 value.

for me worked adding RequestedSessionTimeout: cfg.SessionTimeout

req := &ua.CreateSessionRequest{

   	ClientDescription:       cfg.ClientDescription,

   	EndpointURL:             c.endpointURL,

   	SessionName:             fmt.Sprintf("gopcua-%d", time.Now().UnixNano()),

   	ClientNonce:             nonce,

   	ClientCertificate:       c.cfg.Certificate,

   	RequestedSessionTimeout: cfg.SessionTimeout,
   }

error: unsupported uint16: unsupported or not implemented yet.

Hi!

I'm trying to connect from prosys opcua client (osx) to your example/server (with my changes of course).

Have an issue while connect:

2018/10/01 00:30:44 main.go:79: D Successfully established connection with 172.21.0.1:60570
2018/10/01 00:30:44 main.go:89: D Successfully opened secure channel with 172.21.0.1:60570
2018/10/01 00:30:44 main.go:95: E ReadService error: unsupported uint16: unsupported or not implemented yet.

Any Ideas?

Ready to collaborate.

Update README.md

Before first release, we need to make README.md more friendly for users.

  • Implementation status compared to the spec
  • Good-looking Badges
  • Wording
  • ...

Work in progress in PR #30.

Discussion on compliance tests

In #170 @maurocordioli referenced a test case from the OPC/UA compliance test suite. I think it would be useful to have a framework for writing tests for this suite. Since we don't have a server yet we can pick a reference implementation and run it in a Docker container or as a subprocess.

https://apps.opcfoundation.org/ProfileReporting/testcases/Client/SessionClientGeneralServiceBehaviour.html

I think having a framework for writing tests is more important than test coverage at this point. If we have a framework then others can help filling in the gaps. It would also be useful if we can swap out the server implementation essentially to run integration tests but I don't know how the whole OPC/UA certification process works and whether it matters.

@dwhutchison since you wanted to start working on a server as well we could use this as a testbed for these tests.

What do you all think? Who has experience with this?

Default installation path conflicts with default expectation

By default from sources all would be installed
https://opcuastack.readthedocs.io/en/latest/getting_started/installation.html
to
~/.ASNeG
, which would require from user to do something like

export PATH=$HOME/.ASNeG/usr/bin:$PATH
export LD_LIBRARY_PATH=$HOME/.ASNeG/usr/lib:$LD_LIBRARY_PATH

and it still would not really help, because when doing
https://opcuastack.readthedocs.io/en/latest/getting_started/hello_world.html
user would get the

CMake Error at CMakeLists.txt:82 (include):
  include could not find load file:

    /usr/share/cmake/OpcUaStack3/CMakeOpenSSL.txt

So either detailed explanation how to not get rid of these problems should be included in documentation (what to add to .bashrc, how to configure currently opened shell, etc) or default path should be / instead ~/.ASNeG. It seems that application is designed to be installed to root...

Value nil with ReadResponse service in new version

Hi,

I tried to implement the new version you released in my current project here
https://github.com/felix-lessoer/Machinebeat/blob/v2/beater/client.go

The problem is:
After changing the implementation to use your new client implementation I got no value from ReadResponse anymore.
Trying to get ReadResponse.Results[].Value always leads into nil.

I'm using this public server to test:
endpoint: "opc.tcp://opcuaserver.com:48010"

Node:
id: "AirConditioner_1.Temperature"
namespace: 3

How do you expect to build the ReadRequest?

`
node = client.Node(nodeID)

rh := ua.RequestHeader{}

rv := ua.ReadValueID{}

rv.NodeID = nodeID
rv.AttributeID = 0
rv.IndexRange = ""

qn, err := node.BrowseName()
if err != nil {
	return nil, err
}
rv.DataEncoding = qn

rr := ua.ReadRequest{}
rr.MaxAge = 2000
rr.NodesToRead = []*ua.ReadValueID{&rv}
rr.TimestampsToReturn = ua.TimestampsToReturnBoth
rr.RequestHeader = &rh

m, err := client.Read(&rr)
if err != nil {
	return nil, err
}
value, status := handleReadResponse(m)

`

Simplify error types

Custom errors in errors should not be too many.
e.g. implement ErrDecoding instead of ErrTooShortToDecode and make the message more flexible.

There are some issues when run examples as default config

when we config our opcua server and run examples as default config, we should change fllow func, we should delete :

opt = AuthPolicyID("Anonymous")
opt(c.cfg, c.sessionCfg)

if not, the server will return : The user identity token is not valid.

func NewClient(endpoint string, opts ...Option) *Client {
	c := &Client{
		endpointURL: endpoint,
		cfg:         DefaultClientConfig(),
		sessionCfg:  DefaultSessionConfig(),
	}
	for _, opt := range opts {
		opt(c.cfg, c.sessionCfg)
	}

	// UserIdentityToken was removed from DefaultSessionConfig() so ensure a default still is set
	if c.sessionCfg.UserIdentityToken == nil {
		opt := AuthAnonymous()
		opt(c.cfg, c.sessionCfg)
		opt = AuthPolicyID("Anonymous")
		opt(c.cfg, c.sessionCfg)
	}
	return c
}

Build in 32 bit environment fails

When crosscompiling for a 32 bit environment, I get the following two issues:

.../src/github.com/gopcua/opcua/ua/node_id.go:133:22: constant 4294967295 overflows int
.../src/github.com/gopcua/opcua/ua/node_id.go:250:10: constant 4294967295 overflows int

The first issue arises since strconv.Atoi a few lines earlier returns an int which in my system is 32 bit and thus cannot be compared to an uint32. Using ParseUint instead solved the problem:

id, err := strconv.ParseUint(idval[2:], 10, 32)

The second issue is similar, but for that I made an uglier solution to get it to work by changing the input argument of SetIntID to an uint32 and fiddling a bit with casting etc in the code below.

This relates to commit b9119dc of ua/node_id.go

Validate config

In SecureChannel and Session handling, large part of the required parameters depends on each Config, which is to be created and passed by users.

It causes crash if the parameters in each Config are not properly set. Thus the parameters should be validated when opening SecureChannel/Creating Session and we should notify users of the invalid parameters.

Opcua Client reads server data

Hi I've been looking at your code recently, but I'm not sure how you read server data with client, and I haven't found the location to set the identifier, identifier type, and Namespace Index parameters, can you tell me?

Fix CircleCI

After transferred the repo CCI has not been working.

Unfollow/Stop Building => Setup again did not resolve the issue. Maybe pushing something refleshes it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.